// 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); }