func (w *World) CompileStmtList(fset *token.FileSet, stmts []ast.Stmt) (Code, os.Error) { if len(stmts) == 1 { if s, ok := stmts[0].(*ast.ExprStmt); ok { return w.CompileExpr(fset, s.X) } } errors := new(scanner.ErrorVector) cc := &compiler{fset, errors, 0, 0} cb := newCodeBuf() fc := &funcCompiler{ compiler: cc, fnType: nil, outVarsNamed: false, codeBuf: cb, flow: newFlowBuf(cb), labels: make(map[string]*label), } bc := &blockCompiler{ funcCompiler: fc, block: w.scope.block, } nerr := cc.numError() for _, stmt := range stmts { bc.compileStmt(stmt) } fc.checkLabels() if nerr != cc.numError() { return nil, errors.GetError(scanner.Sorted) } return &stmtCode{w, fc.get()}, nil }
// newScanner creates a new scanner that scans that given input bytes. func newScanner(input []byte) (*scanner.Scanner, *scanner.ErrorVector) { sc := new(scanner.Scanner) ev := new(scanner.ErrorVector) ev.Init() sc.Init("input", input, ev, 0) return sc, ev }
func (w *World) CompileExpr(fset *token.FileSet, e ast.Expr) (Code, os.Error) { errors := new(scanner.ErrorVector) cc := &compiler{fset, errors, 0, 0} ec := cc.compileExpr(w.scope.block, false, e) if ec == nil { return nil, errors.GetError(scanner.Sorted) } var eval func(Value, *Thread) switch t := ec.t.(type) { case *idealIntType: // nothing case *idealFloatType: // nothing default: if tm, ok := t.(*MultiType); ok && len(tm.Elems) == 0 { return &stmtCode{w, code{ec.exec}}, nil } eval = genAssign(ec.t, ec) } return &exprCode{w, ec, eval}, nil }