promote 样例代码的python code:
VariableSymbol.py
- from Symbol import Symbol
- class VariableSymbol( Symbol ):
-     def __init__( self,name, type) :
- super(VariableSymbol,self).__init__(name, type)
Type.py
- from Scope import abstract
- class Type(object) :
-     
-     #def __init__(self):
-     #    if self.__class__ is Scope:
-     # abstract()
-                 
-     #public String getName();
-     def getName(self):
-         abstract()
-     
-     #public int getTypeIndex();
-     def getTypeIndex(self):
- abstract()
SymbolTable.py
- from CymbolListener import CymbolListener
- from BuiltInTypeSymbol import BuiltInTypeSymbol
- from GlobalScope import GlobalScope
- class SymbolTable(object):
-     # arithmetic types defined in order from narrowest to widest
-     #public static final int tUSER = 0; // user-defined type (struct)
-     tUSER = 0
-     #public static final int tBOOLEAN = 1;
-     tBOOLEAN = 1
-     tCHAR = 2
-     tINT = 3
-     tFLOAT = 4
-     tVOID = 5
-     #public static final BuiltInTypeSymbol _boolean =
-     # new BuiltInTypeSymbol("boolean", tBOOLEAN);
-     print 'liu: now init buildin type'
-     _boolean = BuiltInTypeSymbol("boolean", tBOOLEAN)
-     _char = BuiltInTypeSymbol("char", tCHAR)
-     _int = BuiltInTypeSymbol("int", tINT)
-     _float = BuiltInTypeSymbol("float", tFLOAT)
-     _void = BuiltInTypeSymbol("void", tVOID)
-     #public CymbolListener listener =
-     # new CymbolListener() {
-     # public void info(String msg) { System.out.println(msg); }
-     # public void error(String msg) { System.err.println(msg); }
-     # };
-     
-     #listener = CymbolListener() # liunote move to __init__
-     #/** arithmetic types defined in order from narrowest to widest */
-     #public static final Type[] indexToType = {
-     # // 0, 1, 2, 3, 4, 5
-     indexToType = [ None, _boolean, _char, _int, _float, _void ]
-     
-     #/** Map t1 op t2 to result type (_void implies illegal) */
-     #public static final Type[][] arithmeticResultType = new Type[][] {
-     # /* struct boolean char int float, void */
-     # /*struct*/ {_void, _void, _void, _void, _void, _void},
-     # /*boolean*/ {_void, _void, _void, _void, _void, _void},
-     # /*char*/ {_void, _void, _char, _int, _float, _void},
-     # /*int*/ {_void, _void, _int, _int, _float, _void},
-     # /*float*/ {_void, _void, _float, _float, _float, _void},
-     # /*void*/ {_void, _void, _void, _void, _void, _void}
-     #};
-     
-     # liunote math calc type change !!!
-     arithmeticResultType = [
-               [_void, _void, _void, _void, _void, _void ],
-               [_void, _void, _void, _void, _void, _void ],
-               [_void, _void, _char, _int, _float, _void ],
-               [_void, _void, _int, _int, _float, _void ],
-               [_void, _void, _float, _float, _float, _void ],
-               [_void, _void, _void, _void, _void, _void ]
-                            ]
-     #public static final Type[][] relationalResultType = new Type[][] {
-     # /* struct boolean char int float, void */
-     # /*struct*/ {_void, _void, _void, _void, _void, _void},
-     # /*boolean*/ {_void, _void, _void, _void, _void, _void},
-     # /*char*/ {_void, _void, _boolean, _boolean, _boolean, _void},
-     # /*int*/ {_void, _void, _boolean, _boolean, _boolean, _void},
-     # /*float*/ {_void, _void, _boolean, _boolean, _boolean, _void},
-     # /*void*/ {_void, _void, _void, _void, _void, _void}
-     #};
-     
-     # liunote relation calc type change !!!
-     relationalResultType = [
-          [ _void, _void, _void, _void, _void, _void ],
-          [ _void, _void, _void, _void, _void, _void ],
-          [ _void, _void, _boolean, _boolean, _boolean, _void ],
-          [ _void, _void, _boolean, _boolean, _boolean, _void ],
-          [ _void, _void, _boolean, _boolean, _boolean, _void ],
-          [ _void, _void, _void, _void, _void, _void ]
-                            ]
-     #public static final Type[][] equalityResultType = new Type[][] {
-     # /* struct boolean char int float, void */
-     # /*struct*/ {_void, _void, _void, _void, _void, _void},
-     # /*boolean*/ {_void, _boolean, _void, _void, _void, _void},
-     # /*char*/ {_void, _void, _boolean, _boolean, _boolean, _void},
-     # /*int*/ {_void, _void, _boolean, _boolean, _boolean, _void},
-     # /*float*/ {_void, _void, _boolean, _boolean, _boolean, _void},
-     # /*void*/ {_void, _void, _void, _void, _void, _void}
-     #};
-     equalityResultType = [
-         [ _void, _void, _void, _void, _void, _void ],
-         [ _void, _boolean, _void, _void, _void, _void ],
-         [ _void, _void, _boolean, _boolean, _boolean, _void ],
-         [ _void, _void, _boolean, _boolean, _boolean, _void ],
-         [ _void, _void, _boolean, _boolean, _boolean, _void ],
-         [ _void, _void, _void, _void, _void, _void ]
-                          ]
-     
-     #/** Indicate whether a type needs a promotion to a wider type.
-     # * If not null, implies promotion required. Null does NOT imply
-     # * error--it implies no promotion. This works for
-     # * arithmetic, equality, and relational operators in Cymbol.
-     # */
-     #public static final Type[][] promoteFromTo = new Type[][] {
-     # /* struct boolean char int float, void (liunote formal is colum)*/
-     # /*struct*/ {null, null, null, null, null, null},
-     # /*boolean*/ {null, null, null, null, null, null},
-     # /*char*/ {null, null, null, _int, _float, null},
-     # /*int*/ {null, null, null, null, _float, null},
-     # /*float*/ {null, null, null, null, null, null},
-     # /*void*/ {null, null, null, null, null, null}
-     #};
-     
-     promoteFromTo = [
-         [ None, None, None, None, None, None ],
-         [ None, None, None, None, None, None ],
-         [ None, None, None, _int, _float, None ],
-         [ None, None, None, None, _float, None ],
-         [ None, None, None, None, None, None ],
-         [ None, None, None, None, None, None ]
-                    ]
-     #GlobalScope globals = new GlobalScope();
-     #public SymbolTable() { initTypeSystem(); }
-     
-     #protected void initTypeSystem() {
-     # for (Type t : indexToType) {
-     # if ( t!=null ) globals.define((BuiltInTypeSymbol)t);
-     # }
-     #}
-     def initTypeSystem(self):
-         for t in SymbolTable.indexToType:
-             if t != None : self.globals.define(t)
-     def __init__(self):
-         self.listener = CymbolListener()
-         self.globals = GlobalScope()
-         self.initTypeSystem()
-     #public Type getResultType(Type[][] typeTable, CymbolAST a, CymbolAST b) {
-     # int ta = a.evalType.getTypeIndex(); // type index of left operand
-     # int tb = b.evalType.getTypeIndex(); // type index of right operand
-     # Type result = typeTable[ta][tb]; // operation result type
-     # // promote left to right or right to left?
-     # a.promoteToType = promoteFromTo[ta][result.getTypeIndex()];
-     # b.promoteToType = promoteFromTo[tb][result.getTypeIndex()];
-     # return result;
-     #}
-     
-     def getResultType(self,typeTable, a, b) :
-         ta = a.evalType.getTypeIndex() # type index of left operand liunote evalType => int a (a+1.1)'evalType is float!!!
-         tb = b.evalType.getTypeIndex() # type index of right operand
-         result = typeTable[ta][tb] # operation result type
-         
-         # promote left to right or right to left?
-         a.promoteToType = SymbolTable.promoteFromTo[ta][result.getTypeIndex()]
-         b.promoteToType = SymbolTable.promoteFromTo[tb][result.getTypeIndex()]
-         return result
-     #public Type bop(CymbolAST a, CymbolAST b) {
-     # return getResultType(arithmeticResultType, a, b);
-     #}
-     def bop( self,a, b) :
-         return self.getResultType(SymbolTable.arithmeticResultType, a, b) # liunote call myslef method ,param need't self
-     
-     #public Type relop(CymbolAST a, CymbolAST b) {
-     # return getResultType(relationalResultType, a, b);
-     #}
-     def relop(self, a, b) :
-         return self.getResultType(SymbolTable.relationalResultType, a, b)
-     
-     #public Type eqop(CymbolAST a, CymbolAST b) {
-     # return getResultType(equalityResultType, a, b);
-     #}
-     def eqop(self, a, b) :
-         return getResultType(SymbolTable.equalityResultType, a, b)
-     
-     #public Type uminus(CymbolAST a) { return a.evalType; }
-     def uminus(self,a): return a.evalType
-     #public Type unot(CymbolAST a) { return _boolean; }
-     def unot(self, a): return _boolean
-     #public Type arrayIndex(CymbolAST id, CymbolAST index) {
-     # Symbol s = id.scope.resolve(id.getText()); // resolve variable
-     # VariableSymbol vs = (VariableSymbol)s;
-     # id.symbol = vs; // annotate AST
-     # Type t = ((ArrayType)vs.type).elementType; // get element type
-     # int texpr = index.evalType.getTypeIndex();
-     # index.promoteToType = promoteFromTo[texpr][tINT]; // promote index?
-     # return t;
-     #}
-     #arrayRef returns [type] //[Type type]
-     #: ^(INDEX ID expr)
-     # {
-     # $type = self.symtab.arrayIndex($ID, $expr.start);
-     # $start.evalType = $type;
-     # }
-     #;
-     def arrayIndex(self,id, index) :
-         s = id.scope.resolve(id.getText()) # resolve variable # liunote return self.token.text
-         vs = s; # liunote VariableSymbol ???
-         id.symbol = vs; # annotate AST
-         #t = ((ArrayType)vs.type).elementType # get element type
-         #type ID '[]' ('=' expression)? ';' -> ^(VAR_DECL ^('[]' type) ID expression?)
-         t = (vs.type).elementType # liunote vs.type dont cast to (ArrayType) ???
-         
-         texpr = index.evalType.getTypeIndex() # liunote index node get it's evalType [2-1] => _int type 
-         index.promoteToType = SymbolTable.promoteFromTo[texpr][SymbolTable.tINT]; # promote index?
-         return t;
-     #/** For g('q',10), promote 'q' to int, 10 to float
-     # * Given int g(int x, float y) {...} */
-     #public Type call(CymbolAST id, List args) {
-     # Symbol s = id.scope.resolve(id.getText());
-     # MethodSymbol ms = (MethodSymbol)s;
-     # id.symbol = ms;
-     # int i=0;
-     # for (Symbol a : ms.orderedArgs.values() ) { // for each arg
-     # CymbolAST argAST = (CymbolAST)args.get(i++);
-     # // get argument expression type and expected type
-     # Type actualArgType = argAST.evalType;
-     # Type formalArgType = ((VariableSymbol)a).type;
-     # int targ = actualArgType.getTypeIndex();
-     # int tformal = formalArgType.getTypeIndex();
-     # // do we need to promote argument type to defined type?
-     # argAST.promoteToType = promoteFromTo[targ][tformal];
-     # }
-     # return ms.type;
-     #}
-     #call returns [type] //[Type type]
-     #@init {List args = new ArrayList();}
-     #: ^(CALL ID ^(ELIST (expr {args.add($expr.start);})*))
-     # {
-     # $type = symtab.call($ID, args);
-     # $start.evalType = $type;
-     # }
-     #;
-     def call( self,id,args):
-         s = id.scope.resolve(id.getText())
-         ms = s #(MethodSymbol)
-         id.symbol = ms
-         i = 0
-         #for (Symbol a : ms.orderedArgs.values() ) { // for each arg
-         for a in [item[1] for item in ms.orderedArgs]:
-             #CymbolAST argAST = (CymbolAST)args.get(i++);
-             argAST = args[i]
-             
-             # get argument expression type and expected type
-             #Type actualArgType = argAST.evalType;
-             actualArgType = argAST.evalType # liunote only CymbolAST has evalType ???
-             
-             #Type formalArgType = ((VariableSymbol)a).type; # liunote formaltype => int func (int j) ,but call is func (5+1.2)!!!
-             formalArgType = a.type # formal is int index 3, actualArg is float index 4 
-                                                               # promote[4][3]= None , int func(float) ,func(5) =>promote[3][4]= _float 
-             #int targ = actualArgType.getTypeIndex();
-             #int tformal = formalArgType.getTypeIndex();
-             targ = actualArgType.getTypeIndex()
-             tformal = formalArgType.getTypeIndex()
-             
-             #// do we need to promote argument type to defined type?
-             argAST.promoteToType = SymbolTable.promoteFromTo[targ][tformal]
-             
-             i += 1
-         
-         return ms.type
-     
-     #public Type member(CymbolAST expr, CymbolAST field) {
-     # StructSymbol scope=(StructSymbol)expr.evalType;// get scope of left
-     # Symbol s = scope.resolveMember(field.getText());// resolve ID in scope
-     # field.symbol = s;
-     # return s.type; // return ID's type
-     #}
-     #member returns [type] //[Type type]
-     #: ^('.' expr ID)
-     # {
-     # $type = self.symtab.member($expr.start, $ID); // liunote struct a{ int b,...}[] => a[i].b ??? $expr.start what is ???
-     # $start.evalType = $type; // liunote $expr => class expr_return (see below ), it derive TreeRuleReturnScope
-     # } // $expr'start TreeRuleReturnScope 's start ()
-     # // This is identical to the ParserRuleReturnScope except that
-     # // the start property is a tree nodes not Token object
-     # // when you are parsing trees. To be generic the tree node types
-     # // have to be Object.
-     #public static class expr_return extends TreeRuleReturnScope {
-     # public Type type;
-     #};
-     #// $ANTLR start "expr"
-     #// /Users/parrt/research/book/TPDSL/Book/code/semantics/promote/Types.g:39:1: expr returns [Type type] : ( 'true' | 'false' | CHAR | INT | FLOAT | ID | ^( UNARY_MINUS a= expr ) | ^( UNARY_NOT a= expr ) | member | arrayRef | call | binaryOps );
-     #public final Types.expr_return expr() throws RecognitionException {
-     # Types.expr_return retval = new Types.expr_return(); 
-     
-     def member(self, expr, field) :
-         scope = expr.evalType # (StructSymbol) get scope of left
-         s = scope.resolveMember(field.getText()) # resolve ID in scope
-         field.symbol = s
-         return s.type # return ID's type
-     
-     # assignnment stuff (arg assignment in call())
-     #public void declinit(CymbolAST id, CymbolAST init) {
-     # int te = init.evalType.getTypeIndex(); //promote expr to decl type?
-     # int tdecl = id.symbol.type.getTypeIndex();
-     # init.promoteToType = promoteFromTo[te][tdecl];
-     #}
-     #// START: datatransfer
-     #decl: ^(VAR_DECL . ID (init=.)?) // call declinit if we have init expr
-     # /*{if ( $init!=null && $init.evalType!=null )
-     # symtab.declinit($ID, $init);}
-     # *//* liunote $init=>CymbolAST */
-     # {if $init!=None and $init.evalType!=None:
-     # self.symtab.declinit($ID, $init);}
-     #;
-     def declinit(self, id, init) :
-         te = init.evalType.getTypeIndex() # promote expr to decl type?
-         tdecl = id.symbol.type.getTypeIndex()
-         init.promoteToType = SymbolTable.promoteFromTo[te][tdecl]
-     #ret : ^('return' v=.) {self.symtab.ret($start.symbol, $v);} //{symtab.ret((MethodSymbol)$start.symbol, $v);} 
-     #;
-     def ret( self,ms, expr) :
-         retType = ms.type; # promote return expr to function decl type? int m1(...) {return a;} a:expr, ms:int 's switch
-         exprType = expr.evalType
-         texpr = exprType.getTypeIndex()
-         tret = retType.getTypeIndex()
-         expr.promoteToType = SymbolTable.promoteFromTo[texpr][tret] # liunote at return get promote type
-     #assignment // don't walk exprs, just examine types; '.' is wildcard
- #: ^('=
Symbol.py
- class Symbol(object): # A generic programming language symbol
-     #public Symbol(String name) { this.name = name; }
-     #public Symbol(String name, Type type) { this(name); this.type = type; }
-     def __init__(self,name,type=None):
-         self.name = '' # liunote use None ???
-         self.scope = None
-         self.type = None
-         self.cymbolast_def = None # Location in AST of ID node liunote where use???
-         
-         self.name = name
-         
-         if type != None:
-             self.type = type
-     #public String getName() { return name; } # liunote getName must define ,for derive Type interface 
-     def getName(self):
-         return self.name
-     #name = property(getName) # liunote for sub get parent's member var !
-     #def getType(self):
-     #    return self.type
-     #type = property(getType) # liunote for sub class instance get parent's member var !
-     #public String toString() {
-     def toString(self):
-         s = "";
-         if self.scope != None : s = self.scope.getScopeName()+".";
-         if self.type != None : return '<' + s + self.getName() + ":" + type + '>'
-         return s + self.getName();
-     #public static String stripBrackets(String s) {
-     def stripBrackets(s):
-         return s[1:len(s)-1] #s.substring(1,s.length()-1)
-     
- stripBrackets = staticmethod(stripBrackets)
StructSymbol.py
- from Type import Type
- from Scope import Scope
- from ScopedSymbol import ScopedSymbol
- from SymbolTable import SymbolTable
- class StructSymbol (ScopedSymbol, Type, Scope):
-     
-     #Map<String, Symbol> fields = new LinkedHashMap<String, Symbol>();
-     #public StructSymbol(String name,Scope parent) {super(name, parent);}
-     def __init__(self,name,parent) :
-         self.fields = []
-         super(MethodSymbol,self).__init__(name, sparent)
-     
-     #/** For a.b, only look in a only to resolve b, not up scope tree */
-     #public Symbol resolveMember(String name) { return fields.get(name); }
-     def resolveMember(self,name):
-         #return fields.get(name)
-         for item in self.fields:
-             if type(item) != tuple:
-                 raise RuntimeError('fields item is not tuple error')
-             else:
-              if item[0] == name:
-                  return item[1]
-         
-     
-     #public Map<String, Symbol> getMembers() { return fields; }
-     def getMembers(self):
-         return fields
-         
-     def get(self,name):
-         for item in self.fields:
-             if type(item) != tuple:
-                 raise RuntimeError('fields item is not tuple')
-             else:
-              if item[0] == name:
-                  return item[1]
-     #public String toString() {
-     def toString(self):
-         #return "struct "+name+":{"+ stripBrackets(fields.keySet().toString())+"}";
-         return "struct " + self.name + "(" + ScopedSymbol.stripBrackets(str([item[0] for item in self.fields])) + ")"
-     
-     #public int getTypeIndex() { return SymbolTable.tUSER; }
-     def getTypeIndex(self): # liunote other is buildin type ,this is user type
- return SymbolTable.tUSER
ScopedSymbol.py
- from Symbol import Symbol
- from Scope import Scope
- #public abstract class ScopedSymbol extends Symbol implements Scope {
- class ScopedSymbol (Symbol, Scope):
-     #Scope enclosingScope;
-     #public ScopedSymbol(String name, Type type, Scope enclosingScope) {
-     # super(name, type);
-     # this.enclosingScope = enclosingScope;
-     #}
-     #public ScopedSymbol(String name, Scope enclosingScope) {
-     # super(name);
-     # this.enclosingScope = enclosingScope;
-     #}
-     
-     def __init__( self,name, enclosingScope,type):
-         
-         if type != None:
-             super(ScopedSymbol,self).__init__(name, type)
-         else:
-             super(ScopedSymbol,self).__init__(name)
-         
-         #if isinstance(enclosingScope,Scope):
-         # self.enclosingScope = enclosingScope # liunote use issubclass ???
-         #else:
-         # raise RuntimeError('enclosingScope is not instance of xScope')
-         
-         # liunote nouse above , when buidin type(derive smbol type) not derive from Scope !!!
-         #print 'liutest enclosingScope'
-         #print enclosingScope
-         self.enclosingScope = enclosingScope
-         
-     #public Symbol resolve(String name) {
-     def resolve(self,name):
-     #s = self.getMembers().get(name) # this getMembers is abstract, subclass must implement this method !
-     s = self.get(name)
-         if s != None: return s
-     
-     #if not here, check any enclosing scope
-     if self.getEnclosingScope() != None :
-         return self.getEnclosingScope().resolve(name)
-         
-     return None # not found
-     
-     #public Symbol resolveType(String name) { return resolve(name); }
-     def resolveType(self,name):
-         return self.resolve(name)
-     
-     def define(self,sym):
-         #self.getMembers().put(sym.name, sym)
-         self.getMembers().append((sym.name, sym))
-     sym.scope = self # track the scope in each symbol
-     # liutest
-     print self.getMembers()
-     def getEnclosingScope(self):
-         return self.enclosingScope
-     
-     def getScopeName(self):
-         return self.name # liunote self.name at Symbol class => property(getName)
-     #/** Indicate how subclasses store scope members. Allows us to
-     # * factor out common code in this class.
-     # */
-     #public abstract Map<String, Symbol> getMembers();
-     def getMembers(self): # ??? liunote if use below get,getMember can discard !
-         abstract()
-     # liunote for list get name     
-     def get(self,name):
- abstract()
Scope.py
- def abstract():
-     raise NotImplementedError("abstract")
- class Scope(object):
-     
-     #def __init__(self):
-         # if self.__class__ is Scope:
-         # abstract()
-     def getScopeName(self):
-             abstract()
-                
-         # Where to look next for symbols 
-         def getEnclosingScope(self):
-             abstract()
-         # Define a symbol in the current scope
-         def define(self,sym):
-             abstract()
-             
-         # Look up name in this scope or in enclosing scope if not here
-         def resolve(self,name):
- abstract()
