mirror of
https://github.com/golang/go
synced 2024-11-26 04:58:00 -07:00
- more work on semantic checks - not yet enabled by default
R=r OCL=13391 CL=13391
This commit is contained in:
parent
84c8d85fe6
commit
b0ada5ddf7
@ -8,15 +8,39 @@ import Globals "globals"
|
||||
import Universe "universe"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Expressions
|
||||
|
||||
export Expr
|
||||
type Expr struct {
|
||||
type Expr interface {
|
||||
}
|
||||
|
||||
|
||||
export BinaryExpr
|
||||
type BinaryExpr struct {
|
||||
typ *Globals.Type;
|
||||
op int;
|
||||
x, y *Expr;
|
||||
x, y Expr;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Statements
|
||||
|
||||
export Stat
|
||||
type Stat struct {
|
||||
// To be completed
|
||||
type Stat interface {
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
E.WriteObjTag(obj.kind);
|
||||
E.WriteString(obj.ident);
|
||||
E.WriteType(obj.typ);
|
||||
E.WritePackage(E.comp.pkgs[obj.pnolev]);
|
||||
//E.WritePackage(E.comp.pkgs[obj.pnolev]);
|
||||
|
||||
switch obj.kind {
|
||||
case Object.BAD: fallthrough;
|
||||
case Object.PACKAGE: fallthrough;
|
||||
case Object.PTYPE:
|
||||
panic "UNREACHABLE";
|
||||
case Object.CONST:
|
||||
E.WriteInt(0); // should be the correct value
|
||||
break;
|
||||
|
||||
case Object.TYPE:
|
||||
// nothing to do
|
||||
|
||||
case Object.VAR:
|
||||
E.WriteInt(0); // should be the correct address/offset
|
||||
|
||||
case Object.FUNC:
|
||||
E.WriteInt(0); // should be the correct address/offset
|
||||
|
||||
default:
|
||||
print "obj.kind = ", obj.kind, "\n";
|
||||
panic "UNREACHABLE";
|
||||
}
|
||||
}
|
||||
@ -200,41 +200,30 @@ func (E *Exporter) WriteType(typ *Globals.Type) {
|
||||
}
|
||||
|
||||
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:
|
||||
E.WriteInt(typ.len_);
|
||||
E.WriteTypeField(typ.elt);
|
||||
E.WriteType(typ.elt);
|
||||
|
||||
case Type.MAP:
|
||||
E.WriteTypeField(typ.key);
|
||||
E.WriteTypeField(typ.elt);
|
||||
E.WriteType(typ.key);
|
||||
E.WriteType(typ.elt);
|
||||
|
||||
case Type.CHANNEL:
|
||||
E.WriteInt(typ.flags);
|
||||
E.WriteTypeField(typ.elt);
|
||||
E.WriteType(typ.elt);
|
||||
|
||||
case Type.FUNCTION:
|
||||
E.WriteInt(typ.flags);
|
||||
fallthrough;
|
||||
case Type.STRUCT: fallthrough;
|
||||
case Type.INTERFACE:
|
||||
E.WriteScope(typ.scope);
|
||||
|
||||
case Type.STRUCT, Type.INTERFACE:
|
||||
E.WriteScope(typ.scope);
|
||||
|
||||
case Type.POINTER: fallthrough;
|
||||
case Type.REFERENCE:
|
||||
E.WriteTypeField(typ.elt);
|
||||
case Type.POINTER, Type.REFERENCE:
|
||||
E.WriteType(typ.elt);
|
||||
|
||||
default:
|
||||
print "typ.form = ", typ.form, "\n";
|
||||
panic "UNREACHABLE";
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ type Type struct {
|
||||
size int; // in bytes
|
||||
len_ int; // array length, no. of parameters (w/o recv)
|
||||
obj *Object; // primary type object or NULL
|
||||
key *Object; // maps
|
||||
elt *Object; // arrays, maps, channels, pointers, references
|
||||
key *Type; // maps
|
||||
elt *Type; // arrays, maps, channels, pointers
|
||||
scope *Scope; // structs, interfaces, functions
|
||||
}
|
||||
|
||||
|
@ -216,15 +216,15 @@ func (I *Importer) ReadType() *Globals.Type {
|
||||
|
||||
case Type.ARRAY:
|
||||
typ.len_ = I.ReadInt();
|
||||
typ.elt = I.ReadTypeField();
|
||||
typ.elt = I.ReadType();
|
||||
|
||||
case Type.MAP:
|
||||
typ.key = I.ReadTypeField();
|
||||
typ.elt = I.ReadTypeField();
|
||||
typ.key = I.ReadType();
|
||||
typ.elt = I.ReadType();
|
||||
|
||||
case Type.CHANNEL:
|
||||
typ.flags = I.ReadInt();
|
||||
typ.elt = I.ReadTypeField();
|
||||
typ.elt = I.ReadType();
|
||||
|
||||
case Type.FUNCTION:
|
||||
typ.flags = I.ReadInt();
|
||||
@ -235,7 +235,7 @@ func (I *Importer) ReadType() *Globals.Type {
|
||||
|
||||
case Type.POINTER: fallthrough;
|
||||
case Type.REFERENCE:
|
||||
typ.elt = I.ReadTypeField();
|
||||
typ.elt = I.ReadType();
|
||||
}
|
||||
|
||||
return ptyp; // only use primary type
|
||||
|
@ -126,11 +126,7 @@ func (P *Parser) Lookup(ident string) *Globals.Object {
|
||||
|
||||
|
||||
func (P *Parser) DeclareInScope(scope *Globals.Scope, obj *Globals.Object) {
|
||||
if !EnableSemanticTests {
|
||||
return;
|
||||
}
|
||||
|
||||
if scope.Lookup(obj.ident) != nil {
|
||||
if EnableSemanticTests && scope.Lookup(obj.ident) != nil {
|
||||
// TODO is this the correct error position?
|
||||
P.Error(obj.pos, `"` + obj.ident + `" is declared already`);
|
||||
return; // don't insert it into the scope
|
||||
@ -283,63 +279,92 @@ func (P *Parser) ParseTypeName() *Globals.Type {
|
||||
|
||||
func (P *Parser) ParseArrayType() *Globals.Type {
|
||||
P.Trace("ArrayType");
|
||||
|
||||
P.Expect(Scanner.LBRACK);
|
||||
typ := Globals.NewType(Type.ARRAY);
|
||||
if P.tok != Scanner.RBRACK {
|
||||
// TODO set typ.len_
|
||||
P.ParseExpression();
|
||||
}
|
||||
P.Expect(Scanner.RBRACK);
|
||||
P.ParseType();
|
||||
typ.elt = P.ParseType();
|
||||
P.Ecart();
|
||||
return Universe.bad_t;
|
||||
|
||||
return typ;
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseChannelType() *Globals.Type {
|
||||
P.Trace("ChannelType");
|
||||
|
||||
P.Expect(Scanner.CHAN);
|
||||
typ := Globals.NewType(Type.CHANNEL);
|
||||
switch P.tok {
|
||||
case Scanner.SEND: fallthrough
|
||||
case Scanner.RECV:
|
||||
case Scanner.SEND:
|
||||
typ.flags = Type.SEND;
|
||||
P.Next();
|
||||
case Scanner.RECV:
|
||||
typ.flags = Type.RECV;
|
||||
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();
|
||||
return Universe.bad_t;
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseParameterSection() {
|
||||
P.Trace("ParameterSection");
|
||||
P.ParseIdentList();
|
||||
P.ParseType();
|
||||
P.ParseVarDeclList();
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseParameterList() {
|
||||
P.Trace("ParameterList");
|
||||
|
||||
P.ParseParameterSection();
|
||||
for P.tok == Scanner.COMMA {
|
||||
P.Next();
|
||||
P.ParseParameterSection();
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseParameters() {
|
||||
P.Trace("Parameters");
|
||||
|
||||
P.Expect(Scanner.LPAREN);
|
||||
if P.tok != Scanner.RPAREN {
|
||||
P.ParseParameterList();
|
||||
}
|
||||
P.Expect(Scanner.RPAREN);
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) TryResult() bool {
|
||||
P.Trace("Result (try)");
|
||||
|
||||
res := false;
|
||||
if P.tok == Scanner.LPAREN {
|
||||
// TODO: here we allow empty returns - should proably fix this
|
||||
@ -349,10 +374,31 @@ func (P *Parser) TryResult() bool {
|
||||
res = P.TryType() != nil;
|
||||
}
|
||||
P.Ecart();
|
||||
|
||||
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
|
||||
//
|
||||
// (params)
|
||||
@ -362,17 +408,33 @@ func (P *Parser) TryResult() bool {
|
||||
// (recv) . (params) type
|
||||
// (recv) . (params) (results)
|
||||
|
||||
func (P *Parser) ParseAnonymousSignature() {
|
||||
func (P *Parser) ParseAnonymousSignature() *Globals.Type {
|
||||
P.Trace("AnonymousSignature");
|
||||
|
||||
P.OpenScope();
|
||||
sig := P.top_scope;
|
||||
p0 := 0;
|
||||
|
||||
recv_pos := P.pos;
|
||||
P.ParseParameters();
|
||||
|
||||
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.ParseParameters();
|
||||
}
|
||||
|
||||
r0 := sig.entries.len_;
|
||||
P.TryResult();
|
||||
P.CloseScope();
|
||||
|
||||
P.Ecart();
|
||||
return MakeFunctionType(sig, p0, r0, true);
|
||||
}
|
||||
|
||||
|
||||
@ -385,75 +447,97 @@ func (P *Parser) ParseAnonymousSignature() {
|
||||
// (recv) name (params) type
|
||||
// (recv) name (params) (results)
|
||||
|
||||
func (P *Parser) ParseNamedSignature() {
|
||||
func (P *Parser) ParseNamedSignature() (name string, typ *Globals.Type) {
|
||||
P.Trace("NamedSignature");
|
||||
|
||||
P.OpenScope();
|
||||
sig := P.top_scope;
|
||||
p0 := 0;
|
||||
|
||||
if P.tok == Scanner.LPAREN {
|
||||
recv_pos := P.pos;
|
||||
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();
|
||||
|
||||
r0 := sig.entries.len_;
|
||||
P.TryResult();
|
||||
P.CloseScope();
|
||||
P.Ecart();
|
||||
|
||||
return name, MakeFunctionType(sig, p0, r0, true);
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseFunctionType() *Globals.Type {
|
||||
P.Trace("FunctionType");
|
||||
|
||||
P.Expect(Scanner.FUNC);
|
||||
P.ParseAnonymousSignature();
|
||||
typ := P.ParseAnonymousSignature();
|
||||
|
||||
P.Ecart();
|
||||
return Universe.bad_t;
|
||||
return typ;
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseMethodDecl() {
|
||||
P.Trace("MethodDecl");
|
||||
|
||||
P.ParseIdent();
|
||||
P.ParseParameters();
|
||||
P.TryResult();
|
||||
P.Optional(Scanner.SEMICOLON);
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseInterfaceType() *Globals.Type {
|
||||
P.Trace("InterfaceType");
|
||||
|
||||
P.Expect(Scanner.INTERFACE);
|
||||
P.Expect(Scanner.LBRACE);
|
||||
P.OpenScope();
|
||||
typ := Globals.NewType(Type.INTERFACE);
|
||||
typ.scope = P.top_scope;
|
||||
for P.tok != Scanner.RBRACE {
|
||||
P.ParseMethodDecl();
|
||||
}
|
||||
P.CloseScope();
|
||||
P.Next();
|
||||
|
||||
P.Ecart();
|
||||
return Universe.bad_t;
|
||||
return typ;
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseMapType() *Globals.Type {
|
||||
P.Trace("MapType");
|
||||
|
||||
P.Expect(Scanner.MAP);
|
||||
P.Expect(Scanner.LBRACK);
|
||||
P.ParseType();
|
||||
typ := Globals.NewType(Type.MAP);
|
||||
typ.key = P.ParseType();
|
||||
P.Expect(Scanner.RBRACK);
|
||||
P.ParseType();
|
||||
typ.elt = P.ParseType();
|
||||
P.Ecart();
|
||||
return Universe.bad_t;
|
||||
|
||||
return typ;
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseFieldDecl() {
|
||||
P.Trace("FieldDecl");
|
||||
|
||||
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.ParseVarDeclList();
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
@ -483,10 +567,19 @@ func (P *Parser) ParseStructType() *Globals.Type {
|
||||
|
||||
func (P *Parser) ParsePointerType() *Globals.Type {
|
||||
P.Trace("PointerType");
|
||||
|
||||
P.Expect(Scanner.MUL);
|
||||
P.ParseType();
|
||||
P.Ecart();
|
||||
return Universe.bad_t;
|
||||
typ := Universe.undef_t;
|
||||
if (EnableSemanticTests && P.tok == Scanner.IDENT && P.Lookup(P.val) == nil) {
|
||||
// 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() {
|
||||
|
||||
func (P *Parser) ParseBlock() {
|
||||
P.Trace("Block");
|
||||
|
||||
P.Expect(Scanner.LBRACE);
|
||||
P.OpenScope();
|
||||
if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON {
|
||||
@ -543,6 +637,7 @@ func (P *Parser) ParseBlock() {
|
||||
P.Optional(Scanner.SEMICOLON);
|
||||
P.CloseScope();
|
||||
P.Expect(Scanner.RBRACE);
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
@ -552,17 +647,20 @@ func (P *Parser) ParseBlock() {
|
||||
|
||||
func (P *Parser) ParseExpressionList() {
|
||||
P.Trace("ExpressionList");
|
||||
|
||||
P.ParseExpression();
|
||||
for P.tok == Scanner.COMMA {
|
||||
P.Next();
|
||||
P.ParseExpression();
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseNew() {
|
||||
P.Trace("New");
|
||||
|
||||
P.Expect(Scanner.NEW);
|
||||
P.Expect(Scanner.LPAREN);
|
||||
P.ParseType();
|
||||
@ -571,20 +669,24 @@ func (P *Parser) ParseNew() {
|
||||
P.ParseExpressionList()
|
||||
}
|
||||
P.Expect(Scanner.RPAREN);
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseFunctionLit() {
|
||||
P.Trace("FunctionLit");
|
||||
|
||||
P.ParseFunctionType();
|
||||
P.ParseBlock();
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseOperand() {
|
||||
P.Trace("Operand");
|
||||
|
||||
switch P.tok {
|
||||
case Scanner.IDENT:
|
||||
P.ParseQualifiedIdent();
|
||||
@ -607,12 +709,14 @@ func (P *Parser) ParseOperand() {
|
||||
P.Error(P.pos, "operand expected");
|
||||
P.Next(); // make progress
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseSelectorOrTypeAssertion() {
|
||||
P.Trace("SelectorOrTypeAssertion");
|
||||
|
||||
P.Expect(Scanner.PERIOD);
|
||||
if P.tok == Scanner.IDENT {
|
||||
P.ParseIdent();
|
||||
@ -621,12 +725,14 @@ func (P *Parser) ParseSelectorOrTypeAssertion() {
|
||||
P.ParseType();
|
||||
P.Expect(Scanner.RPAREN);
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseIndexOrSlice() {
|
||||
P.Trace("IndexOrSlice");
|
||||
|
||||
P.Expect(Scanner.LBRACK);
|
||||
P.ParseExpression();
|
||||
if P.tok == Scanner.COLON {
|
||||
@ -634,23 +740,27 @@ func (P *Parser) ParseIndexOrSlice() {
|
||||
P.ParseExpression();
|
||||
}
|
||||
P.Expect(Scanner.RBRACK);
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseInvocation() {
|
||||
P.Trace("Invocation");
|
||||
|
||||
P.Expect(Scanner.LPAREN);
|
||||
if P.tok != Scanner.RPAREN {
|
||||
P.ParseExpressionList();
|
||||
}
|
||||
P.Expect(Scanner.RPAREN);
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParsePrimaryExpr() {
|
||||
P.Trace("PrimaryExpr");
|
||||
|
||||
P.ParseOperand();
|
||||
for {
|
||||
switch P.tok {
|
||||
@ -665,23 +775,27 @@ func (P *Parser) ParsePrimaryExpr() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParsePrimaryExprList() {
|
||||
P.Trace("PrimaryExprList");
|
||||
|
||||
P.ParsePrimaryExpr();
|
||||
for P.tok == Scanner.COMMA {
|
||||
P.Next();
|
||||
P.ParsePrimaryExpr();
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseUnaryExpr() *AST.Expr {
|
||||
func (P *Parser) ParseUnaryExpr() AST.Expr {
|
||||
P.Trace("UnaryExpr");
|
||||
|
||||
switch P.tok {
|
||||
case Scanner.ADD: fallthrough;
|
||||
case Scanner.SUB: fallthrough;
|
||||
@ -696,6 +810,7 @@ func (P *Parser) ParseUnaryExpr() *AST.Expr {
|
||||
return nil; // TODO fix this
|
||||
}
|
||||
P.ParsePrimaryExpr();
|
||||
|
||||
P.Ecart();
|
||||
return nil; // TODO fix this
|
||||
}
|
||||
@ -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");
|
||||
|
||||
x := P.ParseUnaryExpr();
|
||||
for prec := Precedence(P.tok); prec >= prec1; prec-- {
|
||||
for Precedence(P.tok) == prec {
|
||||
e := new(AST.Expr);
|
||||
e := new(AST.BinaryExpr);
|
||||
e.typ = Universe.undef_t; // TODO fix this
|
||||
e.op = P.tok; // TODO should we use tokens or separate operator constants?
|
||||
e.x = x;
|
||||
@ -744,7 +859,9 @@ func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr {
|
||||
func (P *Parser) ParseExpression() {
|
||||
P.Trace("Expression");
|
||||
indent := P.indent;
|
||||
|
||||
P.ParseBinaryExpr(1);
|
||||
|
||||
if indent != P.indent {
|
||||
panic "imbalanced tracing code";
|
||||
}
|
||||
@ -809,26 +926,31 @@ func (P *Parser) ParseGoStat() {
|
||||
|
||||
func (P *Parser) ParseReturnStat() {
|
||||
P.Trace("ReturnStat");
|
||||
|
||||
P.Expect(Scanner.RETURN);
|
||||
if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE {
|
||||
P.ParseExpressionList();
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseControlFlowStat(tok int) {
|
||||
P.Trace("ControlFlowStat");
|
||||
|
||||
P.Expect(tok);
|
||||
if P.tok == Scanner.IDENT {
|
||||
P.ParseIdent();
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseIfStat() {
|
||||
func (P *Parser) ParseIfStat() *AST.IfStat {
|
||||
P.Trace("IfStat");
|
||||
|
||||
P.Expect(Scanner.IF);
|
||||
P.OpenScope();
|
||||
if P.tok != Scanner.LBRACE {
|
||||
@ -853,12 +975,14 @@ func (P *Parser) ParseIfStat() {
|
||||
}
|
||||
}
|
||||
P.CloseScope();
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseForStat() {
|
||||
P.Trace("ForStat");
|
||||
|
||||
P.Expect(Scanner.FOR);
|
||||
P.OpenScope();
|
||||
if P.tok != Scanner.LBRACE {
|
||||
@ -878,12 +1002,14 @@ func (P *Parser) ParseForStat() {
|
||||
}
|
||||
P.ParseBlock();
|
||||
P.CloseScope();
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseCase() {
|
||||
P.Trace("Case");
|
||||
|
||||
if P.tok == Scanner.CASE {
|
||||
P.Next();
|
||||
P.ParseExpressionList();
|
||||
@ -891,22 +1017,26 @@ func (P *Parser) ParseCase() {
|
||||
P.Expect(Scanner.DEFAULT);
|
||||
}
|
||||
P.Expect(Scanner.COLON);
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseCaseList() {
|
||||
P.Trace("CaseList");
|
||||
|
||||
P.ParseCase();
|
||||
for P.tok == Scanner.CASE || P.tok == Scanner.DEFAULT {
|
||||
P.ParseCase();
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseCaseClause() {
|
||||
P.Trace("CaseClause");
|
||||
|
||||
P.ParseCaseList();
|
||||
if P.tok != Scanner.FALLTHROUGH && P.tok != Scanner.RBRACE {
|
||||
P.ParseStatementList();
|
||||
@ -916,12 +1046,14 @@ func (P *Parser) ParseCaseClause() {
|
||||
P.Next();
|
||||
P.Optional(Scanner.SEMICOLON);
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseSwitchStat() {
|
||||
P.Trace("SwitchStat");
|
||||
|
||||
P.Expect(Scanner.SWITCH);
|
||||
P.OpenScope();
|
||||
if P.tok != Scanner.LBRACE {
|
||||
@ -941,12 +1073,14 @@ func (P *Parser) ParseSwitchStat() {
|
||||
}
|
||||
P.Expect(Scanner.RBRACE);
|
||||
P.CloseScope();
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseCommCase() {
|
||||
P.Trace("CommCase");
|
||||
|
||||
if P.tok == Scanner.CASE {
|
||||
P.Next();
|
||||
if P.tok == Scanner.GTR {
|
||||
@ -968,40 +1102,47 @@ func (P *Parser) ParseCommCase() {
|
||||
P.Expect(Scanner.DEFAULT);
|
||||
}
|
||||
P.Expect(Scanner.COLON);
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseCommClause() {
|
||||
P.Trace("CommClause");
|
||||
|
||||
P.ParseCommCase();
|
||||
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
|
||||
P.ParseStatementList();
|
||||
P.Optional(Scanner.SEMICOLON);
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseRangeStat() bool {
|
||||
P.Trace("RangeStat");
|
||||
|
||||
P.Expect(Scanner.RANGE);
|
||||
P.ParseIdentList();
|
||||
P.Expect(Scanner.DEFINE);
|
||||
P.ParseExpression();
|
||||
P.ParseBlock();
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseSelectStat() bool {
|
||||
P.Trace("SelectStat");
|
||||
|
||||
P.Expect(Scanner.SELECT);
|
||||
P.Expect(Scanner.LBRACE);
|
||||
for P.tok != Scanner.RBRACE {
|
||||
P.ParseCommClause();
|
||||
}
|
||||
P.Next();
|
||||
|
||||
P.Ecart();
|
||||
}
|
||||
|
||||
@ -1009,6 +1150,7 @@ func (P *Parser) ParseSelectStat() bool {
|
||||
func (P *Parser) TryStatement() bool {
|
||||
P.Trace("Statement (try)");
|
||||
indent := P.indent;
|
||||
|
||||
res := true;
|
||||
switch P.tok {
|
||||
case Scanner.CONST: fallthrough;
|
||||
@ -1050,6 +1192,7 @@ func (P *Parser) TryStatement() bool {
|
||||
// no statement found
|
||||
res = false;
|
||||
}
|
||||
|
||||
if indent != P.indent {
|
||||
panic "imbalanced tracing code"
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
// 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
|
||||
ANY,
|
||||
ARRAY, STRUCT, INTERFACE, MAP, CHANNEL, FUNCTION, POINTER, REFERENCE
|
||||
|
||||
|
||||
const /* form */ (
|
||||
// internal types
|
||||
UNDEF = iota; BAD; NIL;
|
||||
@ -23,6 +22,9 @@ const /* form */ (
|
||||
)
|
||||
|
||||
|
||||
export
|
||||
SEND, RECV
|
||||
|
||||
const /* flag */ (
|
||||
SEND = 1 << iota; // chan>
|
||||
RECV; // chan< or method
|
||||
|
Loading…
Reference in New Issue
Block a user