summaryrefslogtreecommitdiff
path: root/parser/expr.go
diff options
context:
space:
mode:
Diffstat (limited to 'parser/expr.go')
-rw-r--r--parser/expr.go47
1 files changed, 28 insertions, 19 deletions
diff --git a/parser/expr.go b/parser/expr.go
index 35e54ff..5a1c670 100644
--- a/parser/expr.go
+++ b/parser/expr.go
@@ -14,6 +14,7 @@ import (
func (p *Parser) parseExpr(in Tokens, typeStr string) (out Tokens, err error) {
log.Println("parseExpr in:", in)
var ops Tokens
+ var ctype string
popop := func() (t scanner.Token) {
l := len(ops) - 1
@@ -62,6 +63,7 @@ func (p *Parser) parseExpr(in Tokens, typeStr string) (out Tokens, err error) {
if i == 0 || in[i-1].Tok.IsOperator() {
// An operator preceded by an operator or no token is unary.
t.Tok = lang.UnaryOp[t.Tok]
+ // FIXME: parsetype for composite if & or *
}
for len(ops) > 0 && p.precedence(t) < p.precedence(ops[len(ops)-1]) {
out = append(out, popop())
@@ -94,7 +96,7 @@ func (p *Parser) parseExpr(in Tokens, typeStr string) (out Tokens, err error) {
t.Str = sc + "/" + t.Str
}
if s != nil && s.Kind == symbol.Type {
- typeStr = s.Type.String()
+ ctype = s.Type.String()
}
out = append(out, t)
if i+1 < len(in) && in[i+1].Tok == lang.Define {
@@ -120,24 +122,31 @@ func (p *Parser) parseExpr(in Tokens, typeStr string) (out Tokens, err error) {
}
case lang.BraceBlock:
- toks, err := p.parseComposite(t.Block(), typeStr)
+ if ctype == "" {
+ // Infer composite inner type from passed typeStr
+ typ := p.Symbols[typeStr].Type.Elem()
+ ctype = typ.String()
+ p.Symbols.Add(symbol.UnsetAddr, ctype, vm.NewValue(typ), symbol.Type, typ, p.funcScope != "")
+ out = append(out, scanner.Token{Tok: lang.Ident, Pos: t.Pos, Str: ctype})
+ }
+ toks, err := p.parseComposite(t.Block(), ctype)
out = append(out, toks...)
if err != nil {
return out, err
}
- ops = append(ops, scanner.Token{Tok: lang.Composite, Pos: t.Pos, Str: typeStr})
+ ops = append(ops, scanner.Token{Tok: lang.Composite, Pos: t.Pos, Str: ctype})
case lang.BracketBlock:
if i == 0 || in[i-1].Tok.IsOperator() {
// array or slice type expression
- typ, err := p.parseTypeExpr(in[i:])
+ typ, n, err := p.parseTypeExpr(in[i:])
if err != nil {
return out, err
}
- typeStr = typ.String()
- p.Symbols.Add(symbol.UnsetAddr, typ.String(), vm.NewValue(typ), symbol.Type, typ, p.funcScope != "")
- out = append(out, scanner.Token{Tok: lang.Ident, Pos: t.Pos, Str: typeStr})
- i++
+ ctype = typ.String()
+ p.Symbols.Add(symbol.UnsetAddr, ctype, vm.NewValue(typ), symbol.Type, typ, p.funcScope != "")
+ out = append(out, scanner.Token{Tok: lang.Ident, Pos: t.Pos, Str: ctype})
+ i += n - 1
break
}
toks, err := p.parseExprStr(t.Block(), typeStr)
@@ -146,7 +155,7 @@ func (p *Parser) parseExpr(in Tokens, typeStr string) (out Tokens, err error) {
}
out = append(out, toks...)
if i < len(in)-2 && in[i+1].Tok == lang.Assign {
- // A brace block followed by assign implies a MapAssing token,
+ // A bracket block followed by assign implies a MapAssing token,
// as assignement to a map element cannot be implemented through a normal Assign.
ops = append(ops, scanner.Token{Tok: lang.MapAssign, Pos: t.Pos})
i++
@@ -155,24 +164,24 @@ func (p *Parser) parseExpr(in Tokens, typeStr string) (out Tokens, err error) {
}
case lang.Struct:
- typ, err := p.parseTypeExpr(in[i : i+2])
+ typ, _, err := p.parseTypeExpr(in[i : i+2])
if err != nil {
return out, err
}
- typeStr = typ.String()
- p.Symbols.Add(symbol.UnsetAddr, typ.String(), vm.NewValue(typ), symbol.Type, typ, p.funcScope != "")
- out = append(out, scanner.Token{Tok: lang.Ident, Pos: t.Pos, Str: typeStr})
- i++ // FIXME: number of tokens to skip should be computed from type parsing.
+ ctype = typ.String()
+ p.Symbols.Add(symbol.UnsetAddr, ctype, vm.NewValue(typ), symbol.Type, typ, p.funcScope != "")
+ out = append(out, scanner.Token{Tok: lang.Ident, Pos: t.Pos, Str: ctype})
+ i++
case lang.Map:
- typ, err := p.parseTypeExpr(in[i:])
+ typ, n, err := p.parseTypeExpr(in[i:])
if err != nil {
return out, err
}
- typeStr = typ.String()
- p.Symbols.Add(symbol.UnsetAddr, typ.String(), vm.NewValue(typ), symbol.Type, typ, p.funcScope != "")
- out = append(out, scanner.Token{Tok: lang.Ident, Pos: t.Pos, Str: typeStr})
- i += 2 // FIXME: number of tokens to skip should be computed from type parsing.
+ ctype = typ.String()
+ p.Symbols.Add(symbol.UnsetAddr, ctype, vm.NewValue(typ), symbol.Type, typ, p.funcScope != "")
+ out = append(out, scanner.Token{Tok: lang.Ident, Pos: t.Pos, Str: ctype})
+ i += n - 1
case lang.Comment: