summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2023-10-13 18:32:13 +0200
committerMarc Vertes <mvertes@free.fr>2023-10-13 18:32:13 +0200
commit36149e5828df1bb35e06905c65f007dd5869aaec (patch)
tree9dcd79d401f7c0dedb62ba33e459765831a10044
parent40a03025bc1883051c921e6619d751cddcaedeeb (diff)
parser: include absolute paths in symbols
-rw-r--r--lang/token.go2
-rw-r--r--parser/compiler.go20
-rw-r--r--parser/interpreter_test.go2
-rw-r--r--parser/parse.go20
-rw-r--r--parser/symbol.go6
-rw-r--r--parser/type.go8
6 files changed, 24 insertions, 34 deletions
diff --git a/lang/token.go b/lang/token.go
index 3a980a4..5347504 100644
--- a/lang/token.go
+++ b/lang/token.go
@@ -101,8 +101,6 @@ const (
CallX
Label
JumpFalse
- Enter // entering in function context
- Exit // exiting from function context
)
func (t TokenId) IsKeyword() bool { return t >= Break && t <= Var }
diff --git a/parser/compiler.go b/parser/compiler.go
index 68f0596..5d07ae5 100644
--- a/parser/compiler.go
+++ b/parser/compiler.go
@@ -44,12 +44,9 @@ func (c *Compiler) AddSym(name string, value any) int {
func (c *Compiler) Codegen(tokens Tokens) (err error) {
fixList := Tokens{}
- function := []string{""}
-
log.Println("Codegen tokens:", tokens)
for i, t := range tokens {
- scope := function[len(function)-1]
switch t.Id {
case lang.Int:
n, err := strconv.Atoi(t.Str)
@@ -91,16 +88,9 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
c.addSym(l, st.Str, nil, symVar, nil, false)
c.Emit(int64(st.Pos), vm.Assign, int64(l))
- case lang.Enter:
- // TODO: merge with label ?
- function = append(function, t.Str[6:])
-
- case lang.Exit:
- function = function[:len(function)-1]
-
case lang.Assign:
st := tokens[i-1]
- s, _, ok := c.getSym(st.Str, scope)
+ s, ok := c.symbols[st.Str]
if !ok {
return fmt.Errorf("symbol not found: %s", st.Str)
}
@@ -120,7 +110,7 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
continue
}
}
- s, _, ok := c.getSym(t.Str, scope)
+ s, ok := c.symbols[t.Str]
if !ok {
return fmt.Errorf("symbol not found: %s", t.Str)
}
@@ -132,8 +122,8 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
case lang.Label:
// If the label is a function, the symbol already exists
- s, _, ok := c.getSym(t.Str, scope)
lc := len(c.Code)
+ s, ok := c.symbols[t.Str]
if ok {
s.value = lc
if s.kind == symFunc {
@@ -153,7 +143,7 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
case lang.JumpFalse:
label := t.Str[10:]
i := 0
- if s, _, ok := c.getSym(label, scope); !ok {
+ if s, ok := c.symbols[label]; !ok {
// t.Beg contains the position in code which needs to be fixed.
t.Beg = len(c.Code)
fixList = append(fixList, t)
@@ -165,7 +155,7 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
case lang.Goto:
label := t.Str[5:]
i := 0
- if s, _, ok := c.getSym(label, scope); !ok {
+ if s, ok := c.symbols[label]; !ok {
t.Beg = len(c.Code)
fixList = append(fixList, t)
} else {
diff --git a/parser/interpreter_test.go b/parser/interpreter_test.go
index 7daec1a..7d676d4 100644
--- a/parser/interpreter_test.go
+++ b/parser/interpreter_test.go
@@ -63,7 +63,7 @@ func TestFunc(t *testing.T) {
{src: "func f(a int) int {return a+2}; 7 - f(3)", res: "2"},
{src: "func f(a int) int {return a+2}; f(5) - f(3)", res: "2"},
{src: "func f(a int) int {return a+2}; f(3) - 2", res: "3"},
- {src: "func f(a int, b int, c int) int {return a+b-c} ; f(7, 1, 3)", res: "5"},
+ {src: "func f(a, b, c int) int {return a+b-c} ; f(7, 1, 3)", res: "5"},
})
}
diff --git a/parser/parse.go b/parser/parse.go
index 4ccb151..c51a73b 100644
--- a/parser/parse.go
+++ b/parser/parse.go
@@ -208,10 +208,8 @@ func (p *Parser) ParseFunc(in Tokens) (out Tokens, err error) {
}()
out = Tokens{
- {Id: lang.Enter, Str: "enter " + p.scope},
{Id: lang.Goto, Str: "goto " + fname + "_end"}, // Skip function definition.
- {Id: lang.Label, Pos: in[0].Pos, Str: fname},
- }
+ {Id: lang.Label, Pos: in[0].Pos, Str: fname}}
bi := in.Index(lang.BraceBlock)
if bi < 0 {
@@ -231,10 +229,7 @@ func (p *Parser) ParseFunc(in Tokens) (out Tokens, err error) {
return out, err
}
out = append(out, toks...)
- out = append(out,
- scanner.Token{Id: lang.Label, Str: fname + "_end"},
- scanner.Token{Id: lang.Exit},
- )
+ out = append(out, scanner.Token{Id: lang.Label, Str: fname + "_end"})
log.Println("symbols", p.symbols)
return out, err
}
@@ -325,7 +320,16 @@ func (p *Parser) ParseExpr(in Tokens) (out Tokens, err error) {
t := in[i]
// temporary assumptions: binary operators, returning 1 value
switch t.Id {
- case lang.Ident, lang.Int, lang.String:
+ case lang.Ident:
+ // resolve symbol if not a selector rhs.
+ // TODO: test for selector expr.
+ _, sc, ok := p.getSym(t.Str, p.scope)
+ if ok && sc != "" {
+ t.Str = sc + "/" + t.Str
+ }
+ out = append(out, t)
+ vl++
+ case lang.Int, lang.String:
out = append(out, t)
vl++
case lang.Define, lang.Add, lang.Sub, lang.Assign, lang.Equal, lang.Less:
diff --git a/parser/symbol.go b/parser/symbol.go
index 9975c24..f83ec4e 100644
--- a/parser/symbol.go
+++ b/parser/symbol.go
@@ -34,14 +34,12 @@ func (p *Parser) addSym(i int, name string, v any, k symKind, t reflect.Type, lo
// getSym searches for an existing symbol starting from the deepest scope.
func (p *Parser) getSym(name, scope string) (sym *symbol, sc string, ok bool) {
for {
- if sym, ok = p.symbols[scope+name]; ok {
+ if sym, ok = p.symbols[scope+"/"+name]; ok {
return sym, scope, ok
}
- scope = strings.TrimSuffix(scope, "/")
i := strings.LastIndex(scope, "/")
if i == -1 {
- scope = ""
- break
+ i = 0
}
if scope = scope[:i]; scope == "" {
break
diff --git a/parser/type.go b/parser/type.go
index 77ccc6e..4858d75 100644
--- a/parser/type.go
+++ b/parser/type.go
@@ -84,9 +84,9 @@ func (p *Parser) parseParamTypes(in Tokens, arg bool) (types []reflect.Type, err
// Type was ommitted, apply the previous one from the right.
types = append([]reflect.Type{types[0]}, types...)
if arg {
- p.addSym(-i-2, p.scope+param, nil, symVar, types[0], true)
+ p.addSym(-i-2, p.scope+"/"+param, nil, symVar, types[0], true)
} else {
- p.addSym(i, p.scope+param, nil, symVar, types[0], true)
+ p.addSym(i, p.scope+"/"+param, nil, symVar, types[0], true)
}
continue
}
@@ -97,9 +97,9 @@ func (p *Parser) parseParamTypes(in Tokens, arg bool) (types []reflect.Type, err
}
if param != "" {
if arg {
- p.addSym(-i-2, p.scope+param, nil, symVar, typ, true)
+ p.addSym(-i-2, p.scope+"/"+param, nil, symVar, typ, true)
} else {
- p.addSym(i, p.scope+param, nil, symVar, typ, true)
+ p.addSym(i, p.scope+"/"+param, nil, symVar, typ, true)
}
}
types = append([]reflect.Type{typ}, types...)