def gen(self, frame): f = frame.new_label() t = frame.new_label() temp = frame.alloc_temp(ty.Type.Int) self.jumping(0, f, frame) const = Constant(lexer.Num(1), ty.Type.Int) self.emit(il.Assign(temp, const), frame) self.emit(il.Goto(t), frame) self.emit_label(f, frame) const = Constant(lexer.Num(0), ty.Type.Int) self.emit(il.Assign(temp, const), frame) self.emit_label(t, frame) return temp
def _parse_primary_expression(self, env): """ <primary_expression> Parses the <primary_expression> language structure. primary_expression -> 'constant' | '(' logical_expression ')' | 'identifier' """ token = self._look if self._accept(lexer.Tag.NUM): return ast.Constant(token, ty.Type.Int) elif self._accept(lexer.Tag.NULL): return ast.Constant(lexer.Num(0), ty.Type.Int) elif self._accept('('): logexp = self._parse_logical_expression(env) self._match(')') return logexp self._match(lexer.Tag.ID, 'identifier') id_obj = None try: id_obj = env.find(str(token)) except errors.ParserNameError as e: self._name_error('identifier has not been declared', str(token)) return id_obj
def jumping(self, true_label, false_label, frame): """ Generate Expression's Jumping Code Arguments: true_label: The true branch. false_label: The false branch. """ const = Constant(lexer.Num(0), ty.Type.Int) self.emitjumps(Rel(lexer.Token('>'), self.reduce(frame), const), true_label, false_label, frame)
def reduce(self, frame): func_call = self.gen(frame) for arg in func_call.get_args(): self.emit(il.Param(param=arg), frame) args_count = len(func_call.get_args()) const = Constant(lexer.Num(args_count), ty.Type.Int) self.emit(il.Call(call=func_call.get_id_expr(), n=const), frame) if func_call.get_type() is ty.Type.Void: return None temp = frame.alloc_temp(func_call.get_type()) self.emit(il.LoadRet(temp), frame) return temp
def _parse_array_offset(self, expr, env): """ Parses the array offset. """ self._match('[') num = self._parse_logical_expression(env) self._match(']') of_type = expr.get_type().get_of_type() width = ast.Constant(lexer.Num(of_type.get_width()), ty.Type.Int) expr_id = expr offset = ast.Binary(lexer.Token('*'), num, width) if type(expr) is ast.Access: expr_id = expr.get_access_id() offset = ast.Binary(lexer.Token('+'), expr.get_offset(), offset) return ast.Access(lexer.Word('[]', lexer.Tag.INDEX), of_type, expr_id, offset)
def _parse_ptr_offset(self, expr): """ Parses the pointer offset. """ self._match(lexer.Tag.PTR) token = self._look self._match(lexer.Tag.ID) struct_type = expr.get_type().get_ref_type() struct_field = None try: struct_field = struct_type.get_identifier_table().find(str(token)) except errors.ParserNameError: self._name_error('struct has no such field', str(token)) offset = ast.Constant(lexer.Num(struct_field.get_offset()), ty.Type.Int) return ast.Access(lexer.Word('->', lexer.Tag.INDEX), struct_field.get_type(), expr, offset)
def num_parser(token): next_token = use_token(token, L.Num) return next_token, L.Num(token[0].value)