From 37b9da32d3b911091deb254f6cba2a137c471287 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 12 Oct 2023 10:51:58 +0200 Subject: move to a direct byte code compiler (#8) * chore: refactor to keep only the new parser and bytecode vm * scanner: remove Token.value field * scanner: remove scanner.kind field * chore: move language specification in lang package This avoid a cyclic dependency in scanner_test which can now use the golang/GoSpec language specification for Go. * clean code * scanner: export scanner fields Also parser now generate function calls, including externals. * chore: fix lint issues * parser: handle strings * wip * parser: implement support for 'if, else, else if' statements Resolving labels in the compiler still in progress. * parser: support if statements, improve compiler * improve handling of functions * improve support of local variables * scanner: trim leading and trailing spaces * fixes to make fibonacci work * parser: improve README, fix function parameters parsing --- vm0/func.go | 75 ------------------------------------------------------------- 1 file changed, 75 deletions(-) delete mode 100644 vm0/func.go (limited to 'vm0/func.go') diff --git a/vm0/func.go b/vm0/func.go deleted file mode 100644 index ee503bc..0000000 --- a/vm0/func.go +++ /dev/null @@ -1,75 +0,0 @@ -package vm0 - -import ( - "reflect" - "strings" - - "github.com/gnolang/parscan/parser" -) - -var types = map[string]reflect.Type{ - "int": reflect.TypeOf(0), - "string": reflect.TypeOf(""), -} - -func (i *Interp) callFunc(n *parser.Node) { - fp := i.fp - l := len(i.stack) - nargs := i.stack[l-1].(int) - args := make([]reflect.Value, nargs) - for j := range args { - args[nargs-j-1] = reflect.ValueOf(i.stack[l-2-j]) - } - f := reflect.ValueOf(i.stack[l-2-nargs]) - out := f.Call(args) - i.fp = fp - i.stack = i.stack[:l-2-nargs] - for _, v := range out { - i.push(v.Interface()) - } -} - -func (i *Interp) declareFunc(r *parser.Node, scope string) { - fname := r.Child[0].Content() - - // Add symbols for input and output function arguments. - inArgs := r.Child[1].Child - fscope := strings.TrimPrefix(scope+"/"+fname+"/", "/") - in := make([]reflect.Type, len(inArgs)) - for j, c := range inArgs { - i.sym[fscope+c.Content()] = j - in[j] = types[c.Child[0].Content()] - } - var out []reflect.Type - if len(r.Child) > 3 { // function has return values - if i.IsBlock(r.Child[2]) { - outArgs := r.Child[2].Child - out = make([]reflect.Type, len(outArgs)) - for j, c := range outArgs { - out[j] = types[c.Content()] - } - } else { - out = []reflect.Type{types[r.Child[2].Content()]} - } - } - funT := reflect.FuncOf(in, out, false) - - // Generate a wrapper function which will run function body AST. - f := reflect.MakeFunc(funT, func(args []reflect.Value) (res []reflect.Value) { - i.fp = len(i.stack) // fp will be restored by caller (callFunc). - for _, arg := range args { - i.push(arg.Interface()) - } - if err := i.Run(r.Child[len(r.Child)-1], fscope); err != nil { - panic(err) - } - b := len(i.stack) - len(out) - for j := range out { - res = append(res, reflect.ValueOf(i.stack[b+j])) - } - return res - }) - - // Add a symbol for newly created func. - i.sym[scope+fname] = i.push(f.Interface()) - i.fp -} -- cgit v1.2.3