예제 #1
0
 def declare_assign(self, children) -> List[Command]:
     type, identifier, expr = children
     ident = identifier.ident
     if ident in self.symbol_table:
         raise CompileError("Identifier {} already declared".format(ident))
     if expr.type != type:
         raise CompileError(
             "Identifier {} has been declared as {}, but assigned as {}".
             format(ident, type, expr.type))
     expr_with_ident = Expression(expr.type, expr.value, ident)
     self.symbol_table.store(ident, expr_with_ident)
     return []
예제 #2
0
 def assign_ident(self, children) -> List[Command]:
     identifier, expr = children
     ident = identifier.ident
     if ident not in self.symbol_table:
         raise CompileError(
             "Identifier {} has not been declared".format(ident))
     assigned_type = expr.type
     declared_type = self.symbol_table.get_expression(ident).type
     if assigned_type != declared_type:
         raise CompileError(
             "Identifier {} has been declared as {}, but assigned as {}".
             format(ident, declared_type, assigned_type))
     self.symbol_table.update(ident, expr.value)
     return []
예제 #3
0
 def list_elem(self, children) -> ListElem:
     expr1, expr2 = children
     if not isinstance(expr1.type, ListType):
         raise CompileError(
             "Expression {} has type {} is not a list".format(
                 expr1, expr1.type))
     if expr2.type != Type.int():
         raise CompileError(
             "Expression {} should have type int, but is {}".format(
                 expr2, expr2.type))
     if expr2.value >= len(expr1.value):
         raise CompileError(
             "List {} has length {}, but has been assessed with out-of-range index {}"
             .format(expr1.ident, len(expr1.value), expr2.value))
     return ListElem(expr1.ident, expr1, expr2.value)
예제 #4
0
 def rotate_right(self, children) -> List[Command]:
     expr, = children
     if expr.type != Type.int() and expr.type != Type.decimal():
         raise CompileError(
             "Expression {} should have type int or decimal, but is {}".
             format(expr.value, expr.type))
     return [Command.rotate_right(radians(expr.value))]
예제 #5
0
 def backward(self, children) -> List[Command]:
     expr, = children
     if expr.type != Type.int() and expr.type != Type.decimal():
         raise CompileError(
             "Expression {} should have type int or decimal, but is {}".
             format(expr.value, expr.type))
     return [Command.backward(expr.value)]
예제 #6
0
 def vector_z(self, children) -> VectorElem:
     expr, = children
     if expr.type != Type.vector():
         raise CompileError(
             "Expression {} should have type vector, but is {}".format(
                 expr, expr.type))
     return VectorElem(expr.ident, expr, 2)
예제 #7
0
 def declare(self, children) -> List[Command]:
     type, identifier = children
     ident = identifier.ident
     if ident in self.symbol_table:
         raise CompileError("Identifier {} already declared".format(ident))
     self.symbol_table.store(
         ident, Expression(type, type.default_value, ident=ident))
     return []
예제 #8
0
 def vector(self, children) -> Expression:
     expr1, expr2, expr3 = children
     for expr in [expr1, expr2, expr3]:
         if expr.type != Type.decimal():
             raise CompileError(
                 "Expression {} should have type decimal, but is {}".format(
                     expr, expr.type))
     return Expression(Type.vector(),
                       [expr1.value, expr2.value, expr3.value])
예제 #9
0
 def list(self, children) -> Expression:
     exprs = children
     if len(exprs) == 0:
         return Expression(Type.empty_list(), [])
     if not all(e.type == exprs[0].type for e in exprs):
         raise CompileError(
             "Elements in list {} should have the same type".format(exprs))
     return Expression(Type.list_of(exprs[0].type),
                       [e.value for e in exprs])
예제 #10
0
 def repeat(self, children) -> List[Command]:
     expr = children[0]
     commands = children[1:]
     if expr.type != Type.int():
         raise CompileError(
             "Expression {} should have type int, but is {}".format(
                 expr.value, expr.type))
     times = expr.value
     return commands * times
예제 #11
0
 def expr(self, children) -> Expression:
     child, = children
     assert isinstance(child, AbstractExpression)
     if isinstance(child,
                   Identifier) and child.ident not in self.symbol_table:
         # child.expression is None iff child.ident not in self.symbol_table
         raise CompileError("Identifier {} has not been declared".format(
             child.ident))
     expr = child.to_expression()
     assert expr is not None and isinstance(expr, Expression)
     return expr
예제 #12
0
 def assign_vector_elem(self, children) -> List[Command]:
     vector_elem, expr = children
     ident = vector_elem.ident
     vector = vector_elem.container
     index = vector_elem.index
     if expr.type != Type.decimal():
         raise CompileError(
             "Assigned value {} should have type decimal, but is {}".format(
                 expr.value, expr.type))
     self._update_nested_ident(ident, expr, index)
     return []
예제 #13
0
 def assign_list_elem(self, children) -> List[Command]:
     list_elem, expr = children
     ident = list_elem.ident
     list = list_elem.container
     index = list_elem.index
     assigned_type = expr.type
     declared_type = list.type.elem_type
     if assigned_type != declared_type:
         raise CompileError(
             "Assigned value {} should have type {}, but is {}".format(
                 expr.value, declared_type, assigned_type))
     self._update_nested_ident(ident, expr, index)
     return []