diff options
Diffstat (limited to 'projects/hackc/statements.py')
-rw-r--r-- | projects/hackc/statements.py | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/projects/hackc/statements.py b/projects/hackc/statements.py index 0e257ed..458ba01 100644 --- a/projects/hackc/statements.py +++ b/projects/hackc/statements.py @@ -8,7 +8,13 @@ class Statement: @classmethod def from_tokens(cls, tokens: list) -> tuple: - for StatementClass in [LetStatement, DoStatement, ReturnStatement, IfStatement]: + for StatementClass in [ + LetStatement, + DoStatement, + ReturnStatement, + IfStatement, + WhileStatement, + ]: stmt, dt = StatementClass.from_tokens(tokens) if stmt is not None: return (stmt, dt) @@ -35,6 +41,8 @@ class StatementList: def print_verbose(self): for stmt in self.statements: stmt.print_verbose() + if not self.statements: + print("Do nothing") class LetStatement: @@ -190,3 +198,48 @@ class IfStatement: if self.else_then is not None: print("Else then:") self.else_then.print_verbose() + print("End if") + + +class WhileStatement: + def __init__(self, condition: Expression, do: StatementList): + self.condition = condition + self.do = do + + @classmethod + def from_tokens(cls, tokens: list) -> tuple: + """Construct while statement. + + Format: + 'while' '(' <expression> ')' '{' <statement list> '}' + """ + if len(tokens) < 6 or tokens[0] != "while": + return (None, 0) + + if tokens[1] != LEFT_PAREN: + raise UnexpectedToken(LEFT_PAREN, tokens[1]) + + t = 2 + cond, dt = Expression.from_tokens(tokens[2:]) + if cond is None: + raise JackSyntaxError(f"Expected condition", tokens[2]) + t += dt + + if tokens[t] != RIGHT_PAREN: + raise UnexpectedToken(RIGHT_PAREN, tokens[t]) + if tokens[t + 1] != LEFT_BRACE: + raise UnexpectedToken(LEFT_BRACE, tokens[t + 1]) + t += 2 + + do, dt = StatementList.from_tokens(tokens[t:]) + t += dt + + if tokens[t] != RIGHT_BRACE: + raise UnexpectedToken(RIGHT_BRACE, tokens[t]) + + return (WhileStatement(cond, do), t + 1) + + def print_verbose(self): + print(f"While {self.condition} do:") + self.do.print_verbose() + print("End while") |