Mercurial > lcfOS
diff python/ppci/frontends/ks/parser.py @ 110:9e552d34bd60
Work on compiler
author | Windel Bouwman |
---|---|
date | Fri, 04 Jan 2013 15:25:58 +0100 |
parents | f2d980eef509 |
children |
line wrap: on
line diff
--- a/python/ppci/frontends/ks/parser.py Tue Jan 01 17:17:44 2013 +0100 +++ b/python/ppci/frontends/ks/parser.py Fri Jan 04 15:25:58 2013 +0100 @@ -95,6 +95,7 @@ def parseImport(self): loc = self.getLocation() modname = self.Consume('ID') + # TODO: fix #mod = loadModule(modname) self.setLocation(mod, loc) self.cst.addSymbol(mod) @@ -222,9 +223,10 @@ else: self.Error('Cannot evaluate expression {0}'.format(expr)) - def parseConstExpression(self): + def parseConstant(self): e = self.parseExpression() - return self.evalExpression(e), e.typ + val = self.evalExpression(e) + return Constant(val, e.typ) def parseConstantDeclarations(self): """ Parse const part of a module """ @@ -232,9 +234,10 @@ while self.token.typ == 'ID': i = self.parseIdentDef() self.Consume('=') - constvalue, typ = self.parseConstExpression() + c = self.parseConstant() self.Consume(';') - c = Constant(constvalue, typ, name=i.name, public=i.ispublic) + c.name = i.name + c.public = i.ispublic self.setLocation(c, i.location) self.cst.addSymbol(c) @@ -265,17 +268,17 @@ def parseStructuredType(self): if self.hasConsumed('array'): dimensions = [] - dimensions.append( self.parseConstExpression() ) + dimensions.append( self.parseConstant() ) while self.hasConsumed(','): - dimensions.append( self.parseConstExpression() ) + dimensions.append( self.parseConstant() ) self.Consume('of') arr = self.parseType() - for dimension, consttyp in reversed(dimensions): - if not isType(consttyp, integer): + for dimension in reversed(dimensions): + if not isType(dimension.typ, integer): self.Error('array dimension must be an integer type (not {0})'.format(consttyp)) - if dimension < 2: - self.Error('array dimension must be bigger than 1 (not {0})'.format(dimension)) - arr = ArrayType(dimension, arr) + if dimension.value < 2: + self.Error('array dimension must be bigger than 1 (not {0})'.format(dimension.value)) + arr = ArrayType(dimension.value, arr) return arr elif self.hasConsumed('record'): fields = {} @@ -436,6 +439,7 @@ else: args = [] self.Consume(')') + # Type checking: parameters = procedure.typ.parameters if len(args) != len(parameters): self.Error("Procedure requires {0} arguments, {1} given".format(len(parameters), len(args))) @@ -500,6 +504,7 @@ stmt = self.parseStatementSequence() self.Consume('until') cond = self.parseBoolExpression() + # TODO def parseForStatement(self): loc = self.getLocation() @@ -517,9 +522,10 @@ if not end.typ.isType(integer): self.Error('end expression of a for statement must have integer type') if self.hasConsumed('by'): - increment, typ = self.parseConstExpression() - if not typ.isType(integer): + increment = self.parseConstant() + if not increment.typ.isType(integer): self.Error('Increment must be integer') + increment = increment.value else: increment = 1 assert(type(increment) is int) @@ -530,6 +536,7 @@ def parseAsmcode(self): # TODO: move this to seperate file + # TODO: determine what to do with inline asm? def parseOpcode(): return self.Consume('ID') def parseOperand(): @@ -607,10 +614,10 @@ def parseStatementSequence(self): """ Sequence of statements seperated by ';' """ - statements = [ self.parseStatement() ] + statements = [self.parseStatement()] while self.hasConsumed(';'): - statements.append( self.parseStatement() ) - return StatementSequence( statements ) + statements.append(self.parseStatement()) + return StatementSequence(statements) # Parsing expressions: """ @@ -624,8 +631,35 @@ factor = number | nil | true | false | "(" expression ")" | designator [ actualparameters ] | 'not' factor """ + def getTokenPrecedence(self): + binopPrecs = {} + binopPrecs['and'] = 8 + binopPrecs['or'] = 6 + binopPrecs['<'] = 10 + binopPrecs['>'] = 10 + binopPrecs['='] = 10 + binopPrecs['<='] = 10 + binopPrecs['>='] = 10 + binopPrecs['<>'] = 10 + binopPrecs['+'] = 20 + binopPrecs['-'] = 20 + binopPrecs['*'] = 40 + binopPrecs['/'] = 40 + binopPrecs['div'] = 40 + binopPrecs['mod'] = 40 + + typ = self.token.typ + if typ in binopPrecs: + return binopPrecs[typ] + return 0 + def parsePrimary(self): + pass def parseExpression(self): """ The connector between the boolean and expression domain """ + # TODO: implement precedence bindin + #lhs = self.parsePrimary() + #return self.parseBinopRhs(lhs) + expr = self.parseSimpleExpression() if self.token.typ in ['>=','<=','<','>','<>','=']: relop = self.Consume() @@ -640,7 +674,6 @@ self.Error('Type mismatch in relop') if isType(expr.typ, real) and relop in ['<>', '=']: self.Error('Cannot check real values for equality') - expr = Relop(expr, relop, expr2, boolean) return expr @@ -717,10 +750,10 @@ elif self.token.typ == 'STRING': txt = self.Consume('STRING') return StringConstant(txt) - elif self.token.typ in ['true', 'false']: - val = self.Consume() - val = True if val == 'true' else False - return Constant(val, boolean) + elif self.hasConsumed('true'): + return Constant(True, boolean) + elif self.hasConsumed('false'): + return Constant(False, boolean) elif self.hasConsumed('nil'): return Constant(0, NilType()) elif self.hasConsumed('not'):