def generate(outputDir, db, kernels, libxsmmGenerator, architecture): Expr.analyseKernels(db, kernels) for matrixInfo in db.itervalues(): matrixInfo.generateMemoryLayout(architecture, alignStartrow=matrixInfo.leftMultiplication) for name, kernel in kernels: kernel.generateMemoryLayout(architecture, alignStartrow=True) print('\nKernels') print('-------') for name, kernel in kernels: print(u'{}: {}'.format(name, kernel.symbol)) print('\nMemory layout') print('-------------') keys = db.keys() keys.sort(key=lambda s: s.lower()) for key in keys: name = db[key].name for block in db[key].blocks: print('{:16} {}'.format(name, block)) name = '' generator = Generator.Generator(db, libxsmmGenerator, architecture) generator.generateKernels(outputDir, kernels) generator.generateInitializer(outputDir) generator.generateUnitTests(outputDir, kernels)
def assignment(self) -> Expr.Expr: ''' Suck up what might be an assignment target, or might be an expression. ''' possible_lhs = self.logic_or() ''' If the next token is not "=", we are done, with an expression. ''' if not self.match(EQUAL): return possible_lhs ''' We have "something =" so note the location of the "=" for a possible later error message; then collect the r-value. Note the recursion; We take a = b = c as a = (b = c). ''' error_pos = self.previous() rhs = self.assignment() ''' Now ask, We have something =, but is it variable = or property? ''' if isinstance(possible_lhs, Expr.Variable): return Expr.Assign(possible_lhs.name, rhs) if isinstance(possible_lhs, Expr.Get): return Expr.Set(possible_lhs.object, possible_lhs.name, rhs) ''' Neither, flag an error at the "=" token noted earlier. ''' self.error(error_pos, "Invalid target for assignment")
def generate(outputDir, db, kernels, libxsmmGenerator, architecture, prefix=''): Expr.analyseKernels(db, kernels) for matrixInfo in db.itervalues(): matrixInfo.generateMemoryLayout(architecture, alignStartrow=matrixInfo.leftMultiplication) for prototype in kernels: prototype.kernel.generateMemoryLayout(architecture, alignStartrow=True) print('\nKernels') print('-------') for prototype in kernels: print(u'{}: {}'.format(prototype.name, prototype.kernel.symbol)) print('\nMemory layout') print('-------------') keys = db.keys() keys.sort(key=lambda s: s.lower()) for key in keys: name = db[key].name for block in db[key].blocks: print('{:16} {}'.format(name, block)) name = '' generator = Generator.Generator(db, libxsmmGenerator, architecture, prefix) generator.generateKernels(outputDir, kernels) generator.generateInitializer(outputDir) generator.generateUnitTests(outputDir, kernels)
def main(): astPrinter = AstPrinter() expression = Expr.Binary( Expr.Unary(Token(TokenType.MINUS, '-', None, 1), Expr.Literal(123)), Token(TokenType.STAR, '*', None, 1), Expr.Grouping(Expr.Literal(45.67))) print(astPrinter.print(expression))
def call(self): ast = self.primary() while self.match(TokenType.LEFT_PAREN, TokenType.DOT): op = self.nextToken() if op.type == TokenType.LEFT_PAREN: ast = Expr.Call(ast, op, self.callArgs()) self.consume(TokenType.RIGHT_PAREN, exp=')') else: # op.type == TokenType.DOT ast = Expr.Attrib(ast, op, self.identifier()) return ast
def run_main(): exp = Expr.Binary( Expr.Unary( Token(TokenType.MINUS, "-", null, 1), Expr.Litaral(123)), Toke(TokenType.Star, "*", null, 1), Expr.Grouping( Expr.Literal(45.67))) print(AstPrinter.print(exp))
def expr_unary(expression, variables): count = 0 while expression[count] in unary_functions: count = count + 1 func = expression[:count] func = func + "a" result, next = expr_recurse(expression[count:], variables) e = Expr(func) return ((e.evaluate(Trits(trit_string[result])))[0], next)
def expr_unary(expression, variables): count = 0 while expression[count] in unary_functions: count = count + 1 func = expression[:count] func = func + "a" result, next = expr_recurse(expression[count:], variables) e = Expr(func) return ((e.evaluate(Trits(trit_string[result])))[0], next)
def primary(self) -> Expr.Expr: if self.match(IDENTIFIER): # IDENTIFIER token contains a word, make it into an Expr return Expr.Variable(self.previous()) # handle the keyword values if self.match(FALSE): return Expr.Literal(False) if self.match(TRUE): return Expr.Literal(True) if self.match(NIL): return Expr.Literal(None) if self.match(THIS): return Expr.This(self.previous()) if self.match(SUPER): keyword = self.previous() # save "super" token self.consume(DOT, "Expect '.' after 'super'") method_name = self.consume(IDENTIFIER, "Expect superclass method name.") return Expr.Super(keyword, method_name) # handle literal values if self.match(NUMBER, STRING): return Expr.Literal(self.previous().literal) ''' The only remaining legitimate option is a left paren, which will contain an expression and must be followed by a right paren. What would this code do, one asks, given input of "()"? As Nystrom wrote it (through Chapter 8, maybe it gets improved later?) it will look at the token list of [LEFT_PAREN,RIGHT_PAREN,...]; it will call self.expression to process the list [RIGHT_PAREN,...], and will fall through to be an error below. Thus Lox doesn't support the null expression. I am changing this to recognize "()" and return "(nil)". ''' if self.match(LEFT_PAREN): if self.peek().type == RIGHT_PAREN: grouped_expr = Expr.Literal(None) else: grouped_expr = self.expression() self.consume(RIGHT_PAREN, "Expected ')' after expression") return Expr.Grouping(grouped_expr) ''' This is the basement of the recursive ladder. It only returns a value when there is a match to one of the ttypes it checks for. Ergo all possible Expression token types must be checked-for here, or above here. A token type not explicitly checked-for ends up at this error. This is also where we end up, if there is a binary operator without a left argument, e.g. /5 or (!=3). Per challenge 3, detect that. Note that BANG and MINUS have been dealt with in unary() above. If one of those is not followed by a valid rhs, it is the following character that drops through to here. ''' bad_token = self.peek() if bad_token.type in (PLUS, SLASH, STAR, EQUAL, GREATER, LESS): self.error(bad_token, 'operator requires a left operand') ''' Finally we just don't know what's going on. ''' self.error(bad_token, 'Unanticipated input')
def _literal(self): if self._match(TokenType.ALPHA): return Expr.Literal(self._previous().value) if self._match(TokenType.LEFT_PARAN): expr = self._expression() if self._match(TokenType.RIGHT_PARAN): return Expr.Grouping(expr) else: self.__error("Closing Paranthesis not found") self.__error("Unexpected Token")
def funExpr(self, name=None): if self.consume(TokenType.SEMICOLON): # early declaration return Expr.FuncStmt(name, [], []) self.consume(TokenType.LEFT_PAREN, exp='(') params = [] if not self.consume(TokenType.RIGHT_PAREN): while True: params.append(self.identifier()) if self.consume(TokenType.RIGHT_PAREN): break self.consume(TokenType.COMMA, exp=',') self.consume(TokenType.LEFT_BRACE, exp='{') block = self.scopeStmt() return Expr.FuncStmt(name, params, block)
def clsStmt(self): name = self.identifier() if self.consume(TokenType.SEMICOLON): return Expr.ClassStmt(name, None, []) if self.consume(TokenType.LESS): parent = self.identifier() else: parent = None self.consume(TokenType.LEFT_BRACE, exp='{') members = [] while not self.consume(TokenType.RIGHT_BRACE): members.append(self.funStmt()) return Expr.ClassStmt(name, parent, members)
def primary(self): if self.identifier(exp=None): return Expr.Identifier(self.lastToken()) elif self.match(TokenType.NUMBER, TokenType.STRING, TokenType.TRUE, TokenType.FALSE, TokenType.NIL): return Expr.Literal(self.nextToken()) elif self.consume(TokenType.LEFT_PAREN): ast = self.expression() self.consume(TokenType.RIGHT_PAREN, exp=')') return Expr.Grouping(ast) elif self.consume(TokenType.LAMBDA): return self.funExpr() else: raise self.errUnexpToken("primary expr")
def primary(self): ''' We've reached the end with terminal conditions. This is how we stop the recursive descent Terminals include -> Bools, Null, Numbers, Strings, Parenthetical groups (which as expected have their nested expression start the whole process back up from the top. ''' if self.match(TokenType.THIS): return Expr.This(self.previous()) if self.match(TokenType.FALSE): return Expr.Literal(False) if self.match(TokenType.TRUE): return Expr.Literal(True) if self.match(TokenType.NIL): return Expr.Literal(None) if self.match(TokenType.NUMBER, TokenType.STRING): return Expr.Literal(self.previous().literal) if self.match(TokenType.SUPER): keyword = self.previous() self.consume(TokenType.DOT, "Expect '.' after 'super'.") method = self.consume(TokenType.IDENTIFIER, "Expect superclass method name") return Expr.Super(keyword, method) if self.match(TokenType.IDENTIFIER): return Expr.Variable(self.previous()) if self.match(TokenType.LEFT_PAREN): expr = self.expression() self.consume( TokenType.RIGHT_PAREN, "Expect ')' after expression" ) ## need to find a match otherwise must record as error return Expr.Grouping(expr) self.error(self.peek(), "Expect expression" ) ## indicates we reached a token that can't start an expr
def primary(self) -> Expr.Expr: if self.match(Token.TokenType.FALSE): return Expr.Literal(False) if self.match(Token.TokenType.TRUE): return Expr.Literal(True) if self.match(Token.TokenType.NIL): return Expr.Literal(None) if self.match(Token.TokenType.NUMBER, Token.TokenType.STRING): return Expr.Literal(self.previous().literal) if self.match(Token.TokenType.SUPER): keyword = self.previous() self.consume(Token.TokenType.DOT, "Expect '.' after 'super'.") method = self.consume(Token.TokenType.IDENTIFIER, "Expect superclass method name.") return Expr.Super(keyword, method) if self.match(Token.TokenType.THIS): return Expr.This(self.previous()) if (self.match(Token.TokenType.IDENTIFIER)): return Expr.Variable(self.previous()) if self.match(Token.TokenType.LEFT_PAREN): expression = self.expression() self.consume(Token.TokenType.RIGHT_PAREN, "Expect ')' after expression.") return Expr.Grouping(expression) raise self.error(self.peek(), "Expect expression.")
def logic_or(self) -> Expr.Expr: possible_lhs = self.logic_and() while self.match(OR): operator = self.previous() # save that OR token rhs = self.logic_and() possible_lhs = Expr.Logical(possible_lhs, operator, rhs) return possible_lhs
def logic_and(self) -> Expr.Expr: possible_lhs = self.equality() while self.match(AND): operator = self.previous() rhs = self.equality() possible_lhs = Expr.Logical(possible_lhs, operator, rhs) return possible_lhs
def _kleene(self): left = self._literal() while self._match(TokenType.KLEENE): left = Expr.Kleene(left) return left
def flowStmt(self): tok, value = self.lastToken(), None if tok.type == TokenType.RETURN and not self.match( TokenType.SEMICOLON): value = self.expression() self.endStmt() return Expr.FlowStmt(tok, value)
def forStmt(self): self.consume(TokenType.LEFT_PAREN, exp='(') initial = self.statement( ) # to support varStmt as (var i = 0; ...; ...) if not self.match(TokenType.SEMICOLON): condition = self.expression() else: condition = Expr.Literal(self.currToken()._replace( type=TokenType.TRUE, lexeme='true', literal=None)) self.consume(TokenType.SEMICOLON, exp=';') iteration = self.expression() if not self.match( TokenType.RIGHT_PAREN) else None self.consume(TokenType.RIGHT_PAREN, exp=')') loop = self.statement() return Expr.ScopeStmt( [initial, Expr.WhileStmt(condition, loop, iteration)])
def sequence(self) -> Expr.Expr: result = self.expression() while self.match(COMMA): operator = self.previous() # save the COMMA token rhs = self.sequence() # and around we go! result = Expr.Binary(result, operator, rhs) return result
def unary(self): if self.match(TokenType.BANG, TokenType.MINUS): operator = self.previous() right = self.unary() return Expr.Unary(operator, right) return self.primary()
def logic_or(self) -> Expr.Expr: expr = self.logic_and() while self.match(TokenType.OR): operator = self.previous() right = self.logic_and() expr = Expr.Logical(expr, operator, right) return expr
def unary(self) -> Expr.Expr: if self.match(Token.TokenType.BANG, Token.TokenType.MINUS): operator = self.previous() right = self.unary() return Expr.Unary(operator, right) else: return self.call()
def primary(self): if self.match(TokenType.FALSE): return Expr.Literal(False) if self.match(TokenType.TRUE): return Expr.Literal(True) if self.match(TokenType.NIL): return Expr.Literal(None) if self.match(TokenType.NUMBER, TokenType.STRING): return Expr.Literal(self.previous().literal) if self.match(TokenType.LEFT_PAREN): expr = self.expression() self.consume(TokenType.RIGHT_PAREN, "Expect ')' after expression.") return Expr.Grouping(expr) self.consume(None, "Unexpected token")
def addition(self) -> Expr.Expr: """ Parses a binary expression of additive precedence or higher""" expr = self.multiplication() while self.match(TokenType.MINUS, TokenType.PLUS): operator = self.previous() right = self.multiplication() expr = Expr.Binary(expr, operator, right) return expr
def bitshift(self) -> Expr.Expr: """ Parses a binary expression of bitshift precedence or higher """ expr = self.addition() while self.match(TokenType.GREATER_GREATER, TokenType.LESS_LESS): operator = self.previous() right = self.addition() expr = Expr.Binary(expr, operator, right) return expr
def multiplication(self) -> Expr.Expr: expression = self.unary() while self.match(Token.TokenType.SLASH, Token.TokenType.STAR): operator = self.previous() right = self.unary() expression = Expr.Binary(expression, operator, right) return expression
def addition(self) -> Expr.Expr: expression = self.multiplication() while self.match(Token.TokenType.MINUS, Token.TokenType.PLUS): operator = self.previous() right = self.multiplication() expression = Expr.Binary(expression, operator, right) return expression
def assignment(self) -> Expr.Expr: expression = self._or() if self.match(Token.TokenType.EQUAL): equals = self.previous() value = self.assignment() if type(expression) == Expr.Variable: name = expression.name return Expr.Assign(name, value) elif type(expression) == Expr.Get: get = expression return Expr.Set(get._object, get.name, value) else: self.error(equals, "Invalid assignment target") return expression
def equality(self) -> Expr.Expr: """ Parses a binary expression of equality precedence or higher""" expr = self.comparison() while self.match(TokenType.BANG_EQUAL, TokenType.EQUAL_EQUAL): operator = self.previous() right = self.comparison() expr = Expr.Binary(expr, operator, right) return expr
def bitor(self) -> Expr.Expr: """ Parses a binary expression of bitor precedence or higher """ expr = self.bitxor() while self.match(TokenType.BAR): operator = self.previous() right = self.bitxor() expr = Expr.Binary(expr, operator, right) return expr