h.errpos = pos;
if h.nerrors >= 10 {
- // TODO enable when done with name convention
- //sys.Exit(1);
+ sys.Exit(1);
}
}
}
-func (h *errorHandler) Warning(pos int, msg string) {
- panic("UNIMPLEMENTED");
-}
-
-
func Compile(src_file string, flags *Flags) (*AST.Program, int) {
src, ok := Platform.ReadSourceFile(src_file);
if !ok {
scanner.Init(src, &err, true);
var parser Parser.Parser;
- parser.Open(&scanner, err, flags.Verbose, flags.Sixg, flags.Deps);
+ parser.Open(&scanner, &err, flags.Verbose, flags.Sixg, flags.Deps);
prog := parser.ParseProgram();
type ErrorHandler interface {
Error(pos int, msg string);
- Warning(pos int, msg string);
}
opt_semi bool; // true if semicolon separator is optional in statement list
// Nesting levels
- scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc.
+ expr_lev int; // < 0: in control clause, >= 0: in expression
+ scope_lev int; // 0: global scope, 1: function scope of global functions, etc.
// Scopes
top_scope *SymbolTable.Scope;
P.next();
P.scope_lev = 0;
+ P.expr_lev = 0;
}
P.expect(Scanner.RPAREN);
return &AST.Group{pos, t};
}
-
+
// no type found
return nil;
}
pos := P.pos;
P.expect(Scanner.FUNC);
typ := P.parseSignature();
+ P.expr_lev++;
P.scope_lev++;
body := P.parseBlock(Scanner.LBRACE);
P.scope_lev--;
+ P.expr_lev--;
return &AST.FunctionLit{pos, typ, body};
}
case Scanner.LPAREN:
pos := P.pos;
P.next();
+ P.expr_lev++;
x := P.parseExpression(1);
+ P.expr_lev--;
P.expect(Scanner.RPAREN);
return &AST.Group{pos, x};
pos := P.pos;
P.expect(Scanner.LBRACK);
+ P.expr_lev++;
i := P.parseExpression(0);
+ P.expr_lev--;
P.expect(Scanner.RBRACK);
return &AST.Index{pos, x, i};
func (P *Parser) parseBinaryExpr(prec1 int) AST.Expr
-func (P *Parser) parseCompositeElements() AST.Expr {
+func (P *Parser) parseCompositeElements(close int) AST.Expr {
x := P.parseExpression(0);
if P.tok == Scanner.COMMA {
pos := P.pos;
}
var last *AST.BinaryExpr;
- for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
+ for P.tok != close && P.tok != Scanner.EOF {
y := P.parseExpression(0);
if singles {
}
-func (P *Parser) parseCallOrCompositeLit(f AST.Expr) AST.Expr {
+func (P *Parser) parseCallOrCompositeLit(f AST.Expr, open, close int) AST.Expr {
if P.trace {
defer un(trace(P, "CallOrCompositeLit"));
}
pos := P.pos;
- P.expect(Scanner.LPAREN);
+ P.expect(open);
var args AST.Expr;
- if P.tok != Scanner.RPAREN {
- args = P.parseCompositeElements();
+ if P.tok != close {
+ args = P.parseCompositeElements(close);
}
- P.expect(Scanner.RPAREN);
+ P.expect(close);
- return &AST.Call{pos, f, args};
+ return &AST.Call{pos, open, f, args};
}
switch P.tok {
case Scanner.PERIOD: x = P.parseSelectorOrTypeGuard(x);
case Scanner.LBRACK: x = P.parseIndex(x);
- case Scanner.LPAREN: x = P.parseCallOrCompositeLit(x);
+ // TODO fix once we have decided on literal/conversion syntax
+ case Scanner.LPAREN: x = P.parseCallOrCompositeLit(x, Scanner.LPAREN, Scanner.RPAREN);
+ case Scanner.LBRACE:
+ if P.expr_lev >= 0 {
+ x = P.parseCallOrCompositeLit(x, Scanner.LBRACE, Scanner.RBRACE);
+ } else {
+ return x;
+ }
default:
return x;
}
}
if P.tok != Scanner.LBRACE {
+ prev_lev := P.expr_lev;
+ P.expr_lev = -1;
if P.tok != Scanner.SEMICOLON {
init = P.parseSimpleStat(isForStat);
// TODO check for range clause and exit if found
}
}
}
+ P.expr_lev = prev_lev;
}
return init, expr, post;
func (P *Printer) DoCall(x *AST.Call) {
P.Expr1(x.F, Scanner.HighestPrec);
- P.Token(x.Pos_, Scanner.LPAREN);
+ P.Token(x.Pos_, x.Tok);
P.Expr(x.Args);
- P.Token(0, Scanner.RPAREN);
+ switch x.Tok {
+ case Scanner.LPAREN: P.Token(0, Scanner.RPAREN);
+ case Scanner.LBRACE: P.Token(0, Scanner.RBRACE);
+ }
}
// Declarations
func (P *Printer) DoBadDecl(d *AST.BadDecl) {
- unimplemented();
+ P.String(d.Pos, "<BAD DECL>");
}