Commit b0ada5dd authored by Robert Griesemer's avatar Robert Griesemer

- more work on semantic checks - not yet enabled by default

R=r
OCL=13391
CL=13391
parent 84c8d85f
...@@ -8,15 +8,39 @@ import Globals "globals" ...@@ -8,15 +8,39 @@ import Globals "globals"
import Universe "universe" import Universe "universe"
// ----------------------------------------------------------------------------
// Expressions
export Expr export Expr
type Expr struct { type Expr interface {
}
export BinaryExpr
type BinaryExpr struct {
typ *Globals.Type; typ *Globals.Type;
op int; op int;
x, y *Expr; x, y Expr;
} }
// ----------------------------------------------------------------------------
// Statements
export Stat export Stat
type Stat struct { type Stat interface {
// To be completed }
export Block
type Block struct {
// TODO fill in
}
export IfStat
type IfStat struct {
cond Expr;
then_ Stat;
else_ Stat;
} }
...@@ -149,23 +149,23 @@ func (E *Exporter) WriteObject(obj *Globals.Object) { ...@@ -149,23 +149,23 @@ func (E *Exporter) WriteObject(obj *Globals.Object) {
E.WriteObjTag(obj.kind); E.WriteObjTag(obj.kind);
E.WriteString(obj.ident); E.WriteString(obj.ident);
E.WriteType(obj.typ); E.WriteType(obj.typ);
E.WritePackage(E.comp.pkgs[obj.pnolev]); //E.WritePackage(E.comp.pkgs[obj.pnolev]);
switch obj.kind { switch obj.kind {
case Object.BAD: fallthrough;
case Object.PACKAGE: fallthrough;
case Object.PTYPE:
panic "UNREACHABLE";
case Object.CONST: case Object.CONST:
E.WriteInt(0); // should be the correct value E.WriteInt(0); // should be the correct value
break;
case Object.TYPE: case Object.TYPE:
// nothing to do // nothing to do
case Object.VAR: case Object.VAR:
E.WriteInt(0); // should be the correct address/offset E.WriteInt(0); // should be the correct address/offset
case Object.FUNC: case Object.FUNC:
E.WriteInt(0); // should be the correct address/offset E.WriteInt(0); // should be the correct address/offset
default: default:
print "obj.kind = ", obj.kind, "\n";
panic "UNREACHABLE"; panic "UNREACHABLE";
} }
} }
...@@ -200,41 +200,30 @@ func (E *Exporter) WriteType(typ *Globals.Type) { ...@@ -200,41 +200,30 @@ func (E *Exporter) WriteType(typ *Globals.Type) {
} }
switch typ.form { switch typ.form {
case Type.UNDEF: fallthrough;
case Type.BAD: fallthrough;
case Type.NIL: fallthrough;
case Type.BOOL: fallthrough;
case Type.UINT: fallthrough;
case Type.INT: fallthrough;
case Type.FLOAT: fallthrough;
case Type.STRING: fallthrough;
case Type.ANY:
panic "UNREACHABLE";
case Type.ARRAY: case Type.ARRAY:
E.WriteInt(typ.len_); E.WriteInt(typ.len_);
E.WriteTypeField(typ.elt); E.WriteType(typ.elt);
case Type.MAP: case Type.MAP:
E.WriteTypeField(typ.key); E.WriteType(typ.key);
E.WriteTypeField(typ.elt); E.WriteType(typ.elt);
case Type.CHANNEL: case Type.CHANNEL:
E.WriteInt(typ.flags); E.WriteInt(typ.flags);
E.WriteTypeField(typ.elt); E.WriteType(typ.elt);
case Type.FUNCTION: case Type.FUNCTION:
E.WriteInt(typ.flags); E.WriteInt(typ.flags);
fallthrough; E.WriteScope(typ.scope);
case Type.STRUCT: fallthrough;
case Type.INTERFACE: case Type.STRUCT, Type.INTERFACE:
E.WriteScope(typ.scope); E.WriteScope(typ.scope);
case Type.POINTER: fallthrough; case Type.POINTER, Type.REFERENCE:
case Type.REFERENCE: E.WriteType(typ.elt);
E.WriteTypeField(typ.elt);
default: default:
print "typ.form = ", typ.form, "\n";
panic "UNREACHABLE"; panic "UNREACHABLE";
} }
} }
......
...@@ -32,8 +32,8 @@ type Type struct { ...@@ -32,8 +32,8 @@ type Type struct {
size int; // in bytes size int; // in bytes
len_ int; // array length, no. of parameters (w/o recv) len_ int; // array length, no. of parameters (w/o recv)
obj *Object; // primary type object or NULL obj *Object; // primary type object or NULL
key *Object; // maps key *Type; // maps
elt *Object; // arrays, maps, channels, pointers, references elt *Type; // arrays, maps, channels, pointers
scope *Scope; // structs, interfaces, functions scope *Scope; // structs, interfaces, functions
} }
......
...@@ -216,15 +216,15 @@ func (I *Importer) ReadType() *Globals.Type { ...@@ -216,15 +216,15 @@ func (I *Importer) ReadType() *Globals.Type {
case Type.ARRAY: case Type.ARRAY:
typ.len_ = I.ReadInt(); typ.len_ = I.ReadInt();
typ.elt = I.ReadTypeField(); typ.elt = I.ReadType();
case Type.MAP: case Type.MAP:
typ.key = I.ReadTypeField(); typ.key = I.ReadType();
typ.elt = I.ReadTypeField(); typ.elt = I.ReadType();
case Type.CHANNEL: case Type.CHANNEL:
typ.flags = I.ReadInt(); typ.flags = I.ReadInt();
typ.elt = I.ReadTypeField(); typ.elt = I.ReadType();
case Type.FUNCTION: case Type.FUNCTION:
typ.flags = I.ReadInt(); typ.flags = I.ReadInt();
...@@ -235,7 +235,7 @@ func (I *Importer) ReadType() *Globals.Type { ...@@ -235,7 +235,7 @@ func (I *Importer) ReadType() *Globals.Type {
case Type.POINTER: fallthrough; case Type.POINTER: fallthrough;
case Type.REFERENCE: case Type.REFERENCE:
typ.elt = I.ReadTypeField(); typ.elt = I.ReadType();
} }
return ptyp; // only use primary type return ptyp; // only use primary type
......
...@@ -126,11 +126,7 @@ func (P *Parser) Lookup(ident string) *Globals.Object { ...@@ -126,11 +126,7 @@ func (P *Parser) Lookup(ident string) *Globals.Object {
func (P *Parser) DeclareInScope(scope *Globals.Scope, obj *Globals.Object) { func (P *Parser) DeclareInScope(scope *Globals.Scope, obj *Globals.Object) {
if !EnableSemanticTests { if EnableSemanticTests && scope.Lookup(obj.ident) != nil {
return;
}
if scope.Lookup(obj.ident) != nil {
// TODO is this the correct error position? // TODO is this the correct error position?
P.Error(obj.pos, `"` + obj.ident + `" is declared already`); P.Error(obj.pos, `"` + obj.ident + `" is declared already`);
return; // don't insert it into the scope return; // don't insert it into the scope
...@@ -283,63 +279,92 @@ func (P *Parser) ParseTypeName() *Globals.Type { ...@@ -283,63 +279,92 @@ func (P *Parser) ParseTypeName() *Globals.Type {
func (P *Parser) ParseArrayType() *Globals.Type { func (P *Parser) ParseArrayType() *Globals.Type {
P.Trace("ArrayType"); P.Trace("ArrayType");
P.Expect(Scanner.LBRACK); P.Expect(Scanner.LBRACK);
typ := Globals.NewType(Type.ARRAY);
if P.tok != Scanner.RBRACK { if P.tok != Scanner.RBRACK {
// TODO set typ.len_
P.ParseExpression(); P.ParseExpression();
} }
P.Expect(Scanner.RBRACK); P.Expect(Scanner.RBRACK);
P.ParseType(); typ.elt = P.ParseType();
P.Ecart(); P.Ecart();
return Universe.bad_t;
return typ;
} }
func (P *Parser) ParseChannelType() *Globals.Type { func (P *Parser) ParseChannelType() *Globals.Type {
P.Trace("ChannelType"); P.Trace("ChannelType");
P.Expect(Scanner.CHAN); P.Expect(Scanner.CHAN);
typ := Globals.NewType(Type.CHANNEL);
switch P.tok { switch P.tok {
case Scanner.SEND: fallthrough case Scanner.SEND:
typ.flags = Type.SEND;
P.Next();
case Scanner.RECV: case Scanner.RECV:
typ.flags = Type.RECV;
P.Next(); P.Next();
default:
typ.flags = Type.SEND + Type.RECV;
} }
P.ParseType(); typ.elt = P.ParseType();
P.Ecart();
return typ;
}
func (P *Parser) ParseVarDeclList() {
P.Trace("VarDeclList");
list := P.ParseIdentDeclList(Object.VAR);
typ := P.ParseType(); // TODO should check completeness of types
for p := list.first; p != nil; p = p.next {
p.obj.typ = typ; // TODO should use/have set_type()
}
P.Ecart(); P.Ecart();
return Universe.bad_t;
} }
func (P *Parser) ParseParameterSection() { func (P *Parser) ParseParameterSection() {
P.Trace("ParameterSection"); P.Trace("ParameterSection");
P.ParseIdentList(); P.ParseVarDeclList();
P.ParseType();
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseParameterList() { func (P *Parser) ParseParameterList() {
P.Trace("ParameterList"); P.Trace("ParameterList");
P.ParseParameterSection(); P.ParseParameterSection();
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
P.Next(); P.Next();
P.ParseParameterSection(); P.ParseParameterSection();
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseParameters() { func (P *Parser) ParseParameters() {
P.Trace("Parameters"); P.Trace("Parameters");
P.Expect(Scanner.LPAREN); P.Expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
P.ParseParameterList(); P.ParseParameterList();
} }
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
P.Ecart(); P.Ecart();
} }
func (P *Parser) TryResult() bool { func (P *Parser) TryResult() bool {
P.Trace("Result (try)"); P.Trace("Result (try)");
res := false; res := false;
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
// TODO: here we allow empty returns - should proably fix this // TODO: here we allow empty returns - should proably fix this
...@@ -349,10 +374,31 @@ func (P *Parser) TryResult() bool { ...@@ -349,10 +374,31 @@ func (P *Parser) TryResult() bool {
res = P.TryType() != nil; res = P.TryType() != nil;
} }
P.Ecart(); P.Ecart();
return res; return res;
} }
func MakeFunctionType(sig *Globals.Scope, p0, r0 int, check_recv bool) *Globals.Type {
// Determine if we have a receiver or not.
if p0 > 0 && check_recv {
// method
if p0 != 1 {
panic "p0 != 1";
}
}
typ := Globals.NewType(Type.FUNCTION);
if p0 == 0 {
typ.flags = 0;
} else {
typ.flags = Type.RECV;
}
typ.len_ = r0 - p0;
typ.scope = sig;
return typ;
}
// Anonymous signatures // Anonymous signatures
// //
// (params) // (params)
...@@ -362,17 +408,33 @@ func (P *Parser) TryResult() bool { ...@@ -362,17 +408,33 @@ func (P *Parser) TryResult() bool {
// (recv) . (params) type // (recv) . (params) type
// (recv) . (params) (results) // (recv) . (params) (results)
func (P *Parser) ParseAnonymousSignature() { func (P *Parser) ParseAnonymousSignature() *Globals.Type {
P.Trace("AnonymousSignature"); P.Trace("AnonymousSignature");
P.OpenScope(); P.OpenScope();
sig := P.top_scope;
p0 := 0;
recv_pos := P.pos;
P.ParseParameters(); P.ParseParameters();
if P.tok == Scanner.PERIOD { if P.tok == Scanner.PERIOD {
p0 = sig.entries.len_;
if (p0 != 1) {
P.Error(recv_pos, "must have exactly one receiver")
panic "UNIMPLEMENTED";
// TODO do something useful here
}
P.Next(); P.Next();
P.ParseParameters(); P.ParseParameters();
} }
r0 := sig.entries.len_;
P.TryResult(); P.TryResult();
P.CloseScope(); P.CloseScope();
P.Ecart(); P.Ecart();
return MakeFunctionType(sig, p0, r0, true);
} }
...@@ -385,75 +447,97 @@ func (P *Parser) ParseAnonymousSignature() { ...@@ -385,75 +447,97 @@ func (P *Parser) ParseAnonymousSignature() {
// (recv) name (params) type // (recv) name (params) type
// (recv) name (params) (results) // (recv) name (params) (results)
func (P *Parser) ParseNamedSignature() { func (P *Parser) ParseNamedSignature() (name string, typ *Globals.Type) {
P.Trace("NamedSignature"); P.Trace("NamedSignature");
P.OpenScope(); P.OpenScope();
sig := P.top_scope;
p0 := 0;
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
recv_pos := P.pos;
P.ParseParameters(); P.ParseParameters();
p0 = sig.entries.len_;
if (p0 != 1) {
print "p0 = ", p0, "\n";
P.Error(recv_pos, "must have exactly one receiver")
panic "UNIMPLEMENTED";
// TODO do something useful here
}
} }
P.ParseIdent(); // function name
name = P.ParseIdent();
P.ParseParameters(); P.ParseParameters();
r0 := sig.entries.len_;
P.TryResult(); P.TryResult();
P.CloseScope(); P.CloseScope();
P.Ecart();
return name, MakeFunctionType(sig, p0, r0, true);
} }
func (P *Parser) ParseFunctionType() *Globals.Type { func (P *Parser) ParseFunctionType() *Globals.Type {
P.Trace("FunctionType"); P.Trace("FunctionType");
P.Expect(Scanner.FUNC); P.Expect(Scanner.FUNC);
P.ParseAnonymousSignature(); typ := P.ParseAnonymousSignature();
P.Ecart(); P.Ecart();
return Universe.bad_t; return typ;
} }
func (P *Parser) ParseMethodDecl() { func (P *Parser) ParseMethodDecl() {
P.Trace("MethodDecl"); P.Trace("MethodDecl");
P.ParseIdent(); P.ParseIdent();
P.ParseParameters(); P.ParseParameters();
P.TryResult(); P.TryResult();
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseInterfaceType() *Globals.Type { func (P *Parser) ParseInterfaceType() *Globals.Type {
P.Trace("InterfaceType"); P.Trace("InterfaceType");
P.Expect(Scanner.INTERFACE); P.Expect(Scanner.INTERFACE);
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope(); P.OpenScope();
typ := Globals.NewType(Type.INTERFACE);
typ.scope = P.top_scope;
for P.tok != Scanner.RBRACE { for P.tok != Scanner.RBRACE {
P.ParseMethodDecl(); P.ParseMethodDecl();
} }
P.CloseScope(); P.CloseScope();
P.Next(); P.Next();
P.Ecart(); P.Ecart();
return Universe.bad_t; return typ;
} }
func (P *Parser) ParseMapType() *Globals.Type { func (P *Parser) ParseMapType() *Globals.Type {
P.Trace("MapType"); P.Trace("MapType");
P.Expect(Scanner.MAP); P.Expect(Scanner.MAP);
P.Expect(Scanner.LBRACK); P.Expect(Scanner.LBRACK);
P.ParseType(); typ := Globals.NewType(Type.MAP);
typ.key = P.ParseType();
P.Expect(Scanner.RBRACK); P.Expect(Scanner.RBRACK);
P.ParseType(); typ.elt = P.ParseType();
P.Ecart(); P.Ecart();
return Universe.bad_t;
return typ;
} }
func (P *Parser) ParseFieldDecl() { func (P *Parser) ParseFieldDecl() {
P.Trace("FieldDecl"); P.Trace("FieldDecl");
P.ParseVarDeclList();
list := P.ParseIdentDeclList(Object.VAR);
typ := P.ParseType(); // TODO should check completeness of types
for p := list.first; p != nil; p = p.next {
p.obj.typ = typ; // TODO should use/have set_type()
}
P.Ecart(); P.Ecart();
} }
...@@ -483,10 +567,19 @@ func (P *Parser) ParseStructType() *Globals.Type { ...@@ -483,10 +567,19 @@ func (P *Parser) ParseStructType() *Globals.Type {
func (P *Parser) ParsePointerType() *Globals.Type { func (P *Parser) ParsePointerType() *Globals.Type {
P.Trace("PointerType"); P.Trace("PointerType");
P.Expect(Scanner.MUL); P.Expect(Scanner.MUL);
P.ParseType(); typ := Universe.undef_t;
P.Ecart(); if (EnableSemanticTests && P.tok == Scanner.IDENT && P.Lookup(P.val) == nil) {
return Universe.bad_t; // forward declaration
panic "UNIMPLEMENTED *forward_declared_type";
} else {
typ = Globals.NewType(Type.POINTER);
typ.elt = P.ParseType();
}
P.Ecart();
return typ;
} }
...@@ -535,6 +628,7 @@ func (P *Parser) ParseStatementList() { ...@@ -535,6 +628,7 @@ func (P *Parser) ParseStatementList() {
func (P *Parser) ParseBlock() { func (P *Parser) ParseBlock() {
P.Trace("Block"); P.Trace("Block");
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope(); P.OpenScope();
if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON { if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON {
...@@ -543,6 +637,7 @@ func (P *Parser) ParseBlock() { ...@@ -543,6 +637,7 @@ func (P *Parser) ParseBlock() {
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
P.CloseScope(); P.CloseScope();
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
} }
...@@ -552,17 +647,20 @@ func (P *Parser) ParseBlock() { ...@@ -552,17 +647,20 @@ func (P *Parser) ParseBlock() {
func (P *Parser) ParseExpressionList() { func (P *Parser) ParseExpressionList() {
P.Trace("ExpressionList"); P.Trace("ExpressionList");
P.ParseExpression(); P.ParseExpression();
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
P.Next(); P.Next();
P.ParseExpression(); P.ParseExpression();
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseNew() { func (P *Parser) ParseNew() {
P.Trace("New"); P.Trace("New");
P.Expect(Scanner.NEW); P.Expect(Scanner.NEW);
P.Expect(Scanner.LPAREN); P.Expect(Scanner.LPAREN);
P.ParseType(); P.ParseType();
...@@ -571,20 +669,24 @@ func (P *Parser) ParseNew() { ...@@ -571,20 +669,24 @@ func (P *Parser) ParseNew() {
P.ParseExpressionList() P.ParseExpressionList()
} }
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseFunctionLit() { func (P *Parser) ParseFunctionLit() {
P.Trace("FunctionLit"); P.Trace("FunctionLit");
P.ParseFunctionType(); P.ParseFunctionType();
P.ParseBlock(); P.ParseBlock();
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseOperand() { func (P *Parser) ParseOperand() {
P.Trace("Operand"); P.Trace("Operand");
switch P.tok { switch P.tok {
case Scanner.IDENT: case Scanner.IDENT:
P.ParseQualifiedIdent(); P.ParseQualifiedIdent();
...@@ -607,12 +709,14 @@ func (P *Parser) ParseOperand() { ...@@ -607,12 +709,14 @@ func (P *Parser) ParseOperand() {
P.Error(P.pos, "operand expected"); P.Error(P.pos, "operand expected");
P.Next(); // make progress P.Next(); // make progress
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseSelectorOrTypeAssertion() { func (P *Parser) ParseSelectorOrTypeAssertion() {
P.Trace("SelectorOrTypeAssertion"); P.Trace("SelectorOrTypeAssertion");
P.Expect(Scanner.PERIOD); P.Expect(Scanner.PERIOD);
if P.tok == Scanner.IDENT { if P.tok == Scanner.IDENT {
P.ParseIdent(); P.ParseIdent();
...@@ -621,12 +725,14 @@ func (P *Parser) ParseSelectorOrTypeAssertion() { ...@@ -621,12 +725,14 @@ func (P *Parser) ParseSelectorOrTypeAssertion() {
P.ParseType(); P.ParseType();
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseIndexOrSlice() { func (P *Parser) ParseIndexOrSlice() {
P.Trace("IndexOrSlice"); P.Trace("IndexOrSlice");
P.Expect(Scanner.LBRACK); P.Expect(Scanner.LBRACK);
P.ParseExpression(); P.ParseExpression();
if P.tok == Scanner.COLON { if P.tok == Scanner.COLON {
...@@ -634,23 +740,27 @@ func (P *Parser) ParseIndexOrSlice() { ...@@ -634,23 +740,27 @@ func (P *Parser) ParseIndexOrSlice() {
P.ParseExpression(); P.ParseExpression();
} }
P.Expect(Scanner.RBRACK); P.Expect(Scanner.RBRACK);
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseInvocation() { func (P *Parser) ParseInvocation() {
P.Trace("Invocation"); P.Trace("Invocation");
P.Expect(Scanner.LPAREN); P.Expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
P.ParseExpressionList(); P.ParseExpressionList();
} }
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParsePrimaryExpr() { func (P *Parser) ParsePrimaryExpr() {
P.Trace("PrimaryExpr"); P.Trace("PrimaryExpr");
P.ParseOperand(); P.ParseOperand();
for { for {
switch P.tok { switch P.tok {
...@@ -665,23 +775,27 @@ func (P *Parser) ParsePrimaryExpr() { ...@@ -665,23 +775,27 @@ func (P *Parser) ParsePrimaryExpr() {
return; return;
} }
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParsePrimaryExprList() { func (P *Parser) ParsePrimaryExprList() {
P.Trace("PrimaryExprList"); P.Trace("PrimaryExprList");
P.ParsePrimaryExpr(); P.ParsePrimaryExpr();
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
P.Next(); P.Next();
P.ParsePrimaryExpr(); P.ParsePrimaryExpr();
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseUnaryExpr() *AST.Expr { func (P *Parser) ParseUnaryExpr() AST.Expr {
P.Trace("UnaryExpr"); P.Trace("UnaryExpr");
switch P.tok { switch P.tok {
case Scanner.ADD: fallthrough; case Scanner.ADD: fallthrough;
case Scanner.SUB: fallthrough; case Scanner.SUB: fallthrough;
...@@ -696,6 +810,7 @@ func (P *Parser) ParseUnaryExpr() *AST.Expr { ...@@ -696,6 +810,7 @@ func (P *Parser) ParseUnaryExpr() *AST.Expr {
return nil; // TODO fix this return nil; // TODO fix this
} }
P.ParsePrimaryExpr(); P.ParsePrimaryExpr();
P.Ecart(); P.Ecart();
return nil; // TODO fix this return nil; // TODO fix this
} }
...@@ -721,13 +836,13 @@ func Precedence(tok int) int { ...@@ -721,13 +836,13 @@ func Precedence(tok int) int {
} }
func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr { func (P *Parser) ParseBinaryExpr(prec1 int) AST.Expr {
P.Trace("BinaryExpr"); P.Trace("BinaryExpr");
x := P.ParseUnaryExpr(); x := P.ParseUnaryExpr();
for prec := Precedence(P.tok); prec >= prec1; prec-- { for prec := Precedence(P.tok); prec >= prec1; prec-- {
for Precedence(P.tok) == prec { for Precedence(P.tok) == prec {
e := new(AST.Expr); e := new(AST.BinaryExpr);
e.typ = Universe.undef_t; // TODO fix this e.typ = Universe.undef_t; // TODO fix this
e.op = P.tok; // TODO should we use tokens or separate operator constants? e.op = P.tok; // TODO should we use tokens or separate operator constants?
e.x = x; e.x = x;
...@@ -744,7 +859,9 @@ func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr { ...@@ -744,7 +859,9 @@ func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr {
func (P *Parser) ParseExpression() { func (P *Parser) ParseExpression() {
P.Trace("Expression"); P.Trace("Expression");
indent := P.indent; indent := P.indent;
P.ParseBinaryExpr(1); P.ParseBinaryExpr(1);
if indent != P.indent { if indent != P.indent {
panic "imbalanced tracing code"; panic "imbalanced tracing code";
} }
...@@ -809,26 +926,31 @@ func (P *Parser) ParseGoStat() { ...@@ -809,26 +926,31 @@ func (P *Parser) ParseGoStat() {
func (P *Parser) ParseReturnStat() { func (P *Parser) ParseReturnStat() {
P.Trace("ReturnStat"); P.Trace("ReturnStat");
P.Expect(Scanner.RETURN); P.Expect(Scanner.RETURN);
if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE { if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE {
P.ParseExpressionList(); P.ParseExpressionList();
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseControlFlowStat(tok int) { func (P *Parser) ParseControlFlowStat(tok int) {
P.Trace("ControlFlowStat"); P.Trace("ControlFlowStat");
P.Expect(tok); P.Expect(tok);
if P.tok == Scanner.IDENT { if P.tok == Scanner.IDENT {
P.ParseIdent(); P.ParseIdent();
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseIfStat() { func (P *Parser) ParseIfStat() *AST.IfStat {
P.Trace("IfStat"); P.Trace("IfStat");
P.Expect(Scanner.IF); P.Expect(Scanner.IF);
P.OpenScope(); P.OpenScope();
if P.tok != Scanner.LBRACE { if P.tok != Scanner.LBRACE {
...@@ -853,12 +975,14 @@ func (P *Parser) ParseIfStat() { ...@@ -853,12 +975,14 @@ func (P *Parser) ParseIfStat() {
} }
} }
P.CloseScope(); P.CloseScope();
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseForStat() { func (P *Parser) ParseForStat() {
P.Trace("ForStat"); P.Trace("ForStat");
P.Expect(Scanner.FOR); P.Expect(Scanner.FOR);
P.OpenScope(); P.OpenScope();
if P.tok != Scanner.LBRACE { if P.tok != Scanner.LBRACE {
...@@ -878,12 +1002,14 @@ func (P *Parser) ParseForStat() { ...@@ -878,12 +1002,14 @@ func (P *Parser) ParseForStat() {
} }
P.ParseBlock(); P.ParseBlock();
P.CloseScope(); P.CloseScope();
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseCase() { func (P *Parser) ParseCase() {
P.Trace("Case"); P.Trace("Case");
if P.tok == Scanner.CASE { if P.tok == Scanner.CASE {
P.Next(); P.Next();
P.ParseExpressionList(); P.ParseExpressionList();
...@@ -891,22 +1017,26 @@ func (P *Parser) ParseCase() { ...@@ -891,22 +1017,26 @@ func (P *Parser) ParseCase() {
P.Expect(Scanner.DEFAULT); P.Expect(Scanner.DEFAULT);
} }
P.Expect(Scanner.COLON); P.Expect(Scanner.COLON);
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseCaseList() { func (P *Parser) ParseCaseList() {
P.Trace("CaseList"); P.Trace("CaseList");
P.ParseCase(); P.ParseCase();
for P.tok == Scanner.CASE || P.tok == Scanner.DEFAULT { for P.tok == Scanner.CASE || P.tok == Scanner.DEFAULT {
P.ParseCase(); P.ParseCase();
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseCaseClause() { func (P *Parser) ParseCaseClause() {
P.Trace("CaseClause"); P.Trace("CaseClause");
P.ParseCaseList(); P.ParseCaseList();
if P.tok != Scanner.FALLTHROUGH && P.tok != Scanner.RBRACE { if P.tok != Scanner.FALLTHROUGH && P.tok != Scanner.RBRACE {
P.ParseStatementList(); P.ParseStatementList();
...@@ -916,12 +1046,14 @@ func (P *Parser) ParseCaseClause() { ...@@ -916,12 +1046,14 @@ func (P *Parser) ParseCaseClause() {
P.Next(); P.Next();
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseSwitchStat() { func (P *Parser) ParseSwitchStat() {
P.Trace("SwitchStat"); P.Trace("SwitchStat");
P.Expect(Scanner.SWITCH); P.Expect(Scanner.SWITCH);
P.OpenScope(); P.OpenScope();
if P.tok != Scanner.LBRACE { if P.tok != Scanner.LBRACE {
...@@ -941,12 +1073,14 @@ func (P *Parser) ParseSwitchStat() { ...@@ -941,12 +1073,14 @@ func (P *Parser) ParseSwitchStat() {
} }
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.CloseScope(); P.CloseScope();
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseCommCase() { func (P *Parser) ParseCommCase() {
P.Trace("CommCase"); P.Trace("CommCase");
if P.tok == Scanner.CASE { if P.tok == Scanner.CASE {
P.Next(); P.Next();
if P.tok == Scanner.GTR { if P.tok == Scanner.GTR {
...@@ -968,40 +1102,47 @@ func (P *Parser) ParseCommCase() { ...@@ -968,40 +1102,47 @@ func (P *Parser) ParseCommCase() {
P.Expect(Scanner.DEFAULT); P.Expect(Scanner.DEFAULT);
} }
P.Expect(Scanner.COLON); P.Expect(Scanner.COLON);
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseCommClause() { func (P *Parser) ParseCommClause() {
P.Trace("CommClause"); P.Trace("CommClause");
P.ParseCommCase(); P.ParseCommCase();
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE { if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
P.ParseStatementList(); P.ParseStatementList();
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseRangeStat() bool { func (P *Parser) ParseRangeStat() bool {
P.Trace("RangeStat"); P.Trace("RangeStat");
P.Expect(Scanner.RANGE); P.Expect(Scanner.RANGE);
P.ParseIdentList(); P.ParseIdentList();
P.Expect(Scanner.DEFINE); P.Expect(Scanner.DEFINE);
P.ParseExpression(); P.ParseExpression();
P.ParseBlock(); P.ParseBlock();
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseSelectStat() bool { func (P *Parser) ParseSelectStat() bool {
P.Trace("SelectStat"); P.Trace("SelectStat");
P.Expect(Scanner.SELECT); P.Expect(Scanner.SELECT);
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
for P.tok != Scanner.RBRACE { for P.tok != Scanner.RBRACE {
P.ParseCommClause(); P.ParseCommClause();
} }
P.Next(); P.Next();
P.Ecart(); P.Ecart();
} }
...@@ -1009,6 +1150,7 @@ func (P *Parser) ParseSelectStat() bool { ...@@ -1009,6 +1150,7 @@ func (P *Parser) ParseSelectStat() bool {
func (P *Parser) TryStatement() bool { func (P *Parser) TryStatement() bool {
P.Trace("Statement (try)"); P.Trace("Statement (try)");
indent := P.indent; indent := P.indent;
res := true; res := true;
switch P.tok { switch P.tok {
case Scanner.CONST: fallthrough; case Scanner.CONST: fallthrough;
...@@ -1050,6 +1192,7 @@ func (P *Parser) TryStatement() bool { ...@@ -1050,6 +1192,7 @@ func (P *Parser) TryStatement() bool {
// no statement found // no statement found
res = false; res = false;
} }
if indent != P.indent { if indent != P.indent {
panic "imbalanced tracing code" panic "imbalanced tracing code"
} }
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package Scope
import Globals "Globals"
type Scope Globals.Scope
func New(parent *Scope) *Scope {
panic "UNIMPLEMENTED";
return nil;
}
...@@ -10,7 +10,6 @@ export ...@@ -10,7 +10,6 @@ export
ANY, ANY,
ARRAY, STRUCT, INTERFACE, MAP, CHANNEL, FUNCTION, POINTER, REFERENCE ARRAY, STRUCT, INTERFACE, MAP, CHANNEL, FUNCTION, POINTER, REFERENCE
const /* form */ ( const /* form */ (
// internal types // internal types
UNDEF = iota; BAD; NIL; UNDEF = iota; BAD; NIL;
...@@ -23,6 +22,9 @@ const /* form */ ( ...@@ -23,6 +22,9 @@ const /* form */ (
) )
export
SEND, RECV
const /* flag */ ( const /* flag */ (
SEND = 1 << iota; // chan> SEND = 1 << iota; // chan>
RECV; // chan< or method RECV; // chan< or method
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment