mirror of
https://github.com/golang/go
synced 2024-11-23 00:20:12 -07:00
839a68469b
TBR=r OCL=23121 CL=23127
219 lines
4.4 KiB
Go
219 lines
4.4 KiB
Go
// 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 AST
|
|
|
|
import Globals "globals"
|
|
import GlobalObject "object"
|
|
import Type "type"
|
|
import Universe "universe"
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Expressions
|
|
|
|
const /* op */ (
|
|
LITERAL = iota;
|
|
OBJECT;
|
|
DEREF;
|
|
SELECT;
|
|
CALL;
|
|
TUPLE;
|
|
)
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Literals
|
|
|
|
type Literal struct {
|
|
pos_ int;
|
|
typ_ *Globals.Type;
|
|
b bool;
|
|
i int;
|
|
f float;
|
|
s string;
|
|
}
|
|
|
|
|
|
func (x *Literal) op() int { return LITERAL; }
|
|
func (x *Literal) pos() int { return x.pos_; }
|
|
func (x *Literal) typ() *Globals.Type { return x.typ_; }
|
|
|
|
|
|
func NewLiteral(pos int, typ *Globals.Type) *Literal {
|
|
x := new(Literal);
|
|
x.pos_ = pos;
|
|
x.typ_ = typ;
|
|
return x;
|
|
}
|
|
|
|
|
|
var Bad, True, False, Nil *Literal;
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Objects
|
|
|
|
// NOTE We could use Globals.Object directly if we'd added a typ()
|
|
// method to its interface. However, this would require renaming the
|
|
// typ field everywhere... - Need to think about accessors again.
|
|
type Object struct {
|
|
pos_ int;
|
|
obj *Globals.Object;
|
|
}
|
|
|
|
|
|
func (x *Object) op() int { return OBJECT; }
|
|
func (x *Object) pos() int { return x.pos_; }
|
|
func (x *Object) typ() *Globals.Type { return x.obj.typ; }
|
|
|
|
|
|
func NewObject(pos int, obj* Globals.Object) *Object {
|
|
x := new(Object);
|
|
x.pos_ = pos;
|
|
x.obj = obj;
|
|
return x;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Derefs
|
|
|
|
// TODO model Deref as unary operation?
|
|
type Deref struct {
|
|
ptr_ Globals.Expr;
|
|
}
|
|
|
|
|
|
func (x *Deref) op() int { return DEREF; }
|
|
func (x *Deref) pos() int { return x.ptr_.pos(); }
|
|
func (x *Deref) typ() *Globals.Type { return x.ptr_.typ().elt; }
|
|
|
|
|
|
func NewDeref(ptr Globals.Expr) *Deref {
|
|
x := new(Deref);
|
|
x.ptr_ = ptr;
|
|
return x;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Selectors
|
|
|
|
// TODO model Selector as binary operation?
|
|
type Selector struct {
|
|
pos_ int;
|
|
typ_ *Globals.Type;
|
|
}
|
|
|
|
|
|
func (x *Selector) op() int { return SELECT; }
|
|
func (x *Selector) pos() int { return x.pos_; }
|
|
func (x *Selector) typ() *Globals.Type { return x.typ_; }
|
|
|
|
|
|
func NewSelector(pos int, typ *Globals.Type) *Selector {
|
|
x := new(Selector);
|
|
x.pos_ = pos;
|
|
x.typ_ = typ;
|
|
return x;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Calls
|
|
|
|
type Call struct {
|
|
recv, callee Globals.Expr;
|
|
args *Globals.List;
|
|
}
|
|
|
|
|
|
func (x *Call) op() int { return CALL; }
|
|
func (x *Call) pos() int { return 0; }
|
|
func (x *Call) typ() *Globals.Type { return nil; }
|
|
|
|
|
|
func NewCall(args *Globals.List) *Call {
|
|
x := new(Call);
|
|
x.args = args;
|
|
return x;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Binary expressions
|
|
|
|
type BinaryExpr struct {
|
|
op_ int;
|
|
pos_ int;
|
|
typ_ *Globals.Type;
|
|
x, y Globals.Expr;
|
|
}
|
|
|
|
|
|
func (x *BinaryExpr) op() int { return x.op_; }
|
|
func (x *BinaryExpr) pos() int { return x.pos_; }
|
|
func (x *BinaryExpr) typ() *Globals.Type { return x.typ_; }
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Tuples
|
|
|
|
type Tuple struct {
|
|
typ_ *Globals.Type;
|
|
list *Globals.List;
|
|
}
|
|
|
|
|
|
func (x *Tuple) op() int { return TUPLE; }
|
|
func (x *Tuple) pos() int { return x.list.first.expr.pos(); }
|
|
func (x *Tuple) typ() *Globals.Type { return x.typ_; }
|
|
|
|
|
|
func NewTuple(list *Globals.List) *Tuple {
|
|
// make corresponding tuple type
|
|
scope := Globals.NewScope(nil);
|
|
for p := list.first; p != nil; p = p.next {
|
|
x := p.expr;
|
|
obj := Globals.NewObject(x.pos(), GlobalObject.FIELD, "");
|
|
obj.typ = x.typ();
|
|
scope.Add(obj);
|
|
}
|
|
typ := Globals.NewType(Type.TUPLE);
|
|
typ.scope = scope;
|
|
|
|
// create the tuple
|
|
x := new(Tuple);
|
|
x.typ_ = typ;
|
|
x.list = list;
|
|
return x;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Statements
|
|
|
|
type Block struct {
|
|
// TODO fill in
|
|
}
|
|
|
|
|
|
type IfStat struct {
|
|
cond Globals.Expr;
|
|
then_ Globals.Stat;
|
|
else_ Globals.Stat;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Initialization
|
|
|
|
func init() {
|
|
Bad = NewLiteral(-1, Universe.bad_t);
|
|
True = NewLiteral(-1, Universe.bool_t); True.b = true;
|
|
False = NewLiteral(-1, Universe.bool_t); False.b = false;
|
|
Nil = NewLiteral(-1, Universe.nil_t);
|
|
}
|