diff options
author | Frederick Yin <fkfd@fkfd.me> | 2022-09-03 11:46:10 +0800 |
---|---|---|
committer | Frederick Yin <fkfd@fkfd.me> | 2022-09-03 11:46:10 +0800 |
commit | dfb5ee45fb68aca09bd0ac9967c6b574f932d39f (patch) | |
tree | a137350c895d6d1a1ff1d9f7ae4db080e07ef877 /projects | |
parent | b1794edb3d76db7c1a86fc14a60bc95b833bc7c7 (diff) |
hackc: While statement
Diffstat (limited to 'projects')
-rw-r--r-- | projects/hackc/classes.py | 16 | ||||
-rw-r--r-- | projects/hackc/statements.py | 55 |
2 files changed, 59 insertions, 12 deletions
diff --git a/projects/hackc/classes.py b/projects/hackc/classes.py index f1358f6..ed69810 100644 --- a/projects/hackc/classes.py +++ b/projects/hackc/classes.py @@ -1,4 +1,4 @@ -from .statements import Statement +from .statements import StatementList from .tokens import Token from .utils import * @@ -210,7 +210,7 @@ class Subroutine: name: Token, params: ParamList, variables: list, - statements: list, + statements: StatementList, ): self.category = category self.type = type @@ -266,13 +266,8 @@ class Subroutine: variables.append(variable) t += dt - statements = [] - while t < len(tokens): - statement, dt = Statement.from_tokens(tokens[t:]) - if statement is None: - break - statements.append(statement) - t += dt + statements, dt = StatementList.from_tokens(tokens[t:]) + t += dt body_close = tokens[t] if body_close != RIGHT_BRACE: @@ -289,6 +284,5 @@ class Subroutine: self.params.print_verbose() for variable in self.variables: variable.print_verbose() - for statement in self.statements: - statement.print_verbose() + self.statements.print_verbose() print(f"End of {self.category} {self.name}") 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") |