func (w *World) CompileStmtList(fset *token.FileSet, stmts []ast.Stmt) (Code, error) { if len(stmts) == 1 { if s, ok := stmts[0].(*ast.ExprStmt); ok { return w.CompileExpr(fset, s.X) } } errors := new(scanner.ErrorList) 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() { errors.Sort() return nil, errors.Err() } return &stmtCode{w, fc.get()}, nil }
func (p *Parser) Ast(fs *token.FileSet, path string, files []string, unsaved map[string]UnsavedDocument) (*ast.File, []*ast.File, error) { ret := make([]*ast.File, len(files)) var retf *ast.File var errors scanner.ErrorList for i, f := range files { f = CanonicalPath(f) var v *ast.File var err error if uns, ok := unsaved[f]; ok { v, err = parser.ParseFile(fs, f, uns.Data, parser.AllErrors) } else { v, err = p.fromCache(fs, f) } if v == nil { return nil, nil, err } ret[i] = v if path == f { retf = ret[i] if perr, ok := err.(scanner.ErrorList); ok { for _, e := range perr { errors.Add(e.Pos, e.Msg) } } } } errors.RemoveMultiples() errors.Sort() var err error if len(errors) != 0 { err = errors } return retf, ret, err }
func (w *World) CompileExpr(fset *token.FileSet, e ast.Expr) (Code, error) { errors := new(scanner.ErrorList) cc := &compiler{fset, errors, 0, 0} ec := cc.compileExpr(w.scope.block, false, e) if ec == nil { errors.Sort() return nil, errors.Err() } 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 }