summaryrefslogtreecommitdiff
path: root/projects/hackc/expressions.py
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@fkfd.me>2022-08-31 16:42:22 +0800
committerFrederick Yin <fkfd@fkfd.me>2022-08-31 16:42:22 +0800
commit61f3490b9e6132cbad70c90637ed349a42fe7704 (patch)
treee9784e13a9d127e59ea00b234ff9af47a65d7505 /projects/hackc/expressions.py
parent75811ebbd166b3cd271bb730323cc7ab4fdcb3a5 (diff)
hackc: i dont even remember
Diffstat (limited to 'projects/hackc/expressions.py')
-rw-r--r--projects/hackc/expressions.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/projects/hackc/expressions.py b/projects/hackc/expressions.py
new file mode 100644
index 0000000..de58528
--- /dev/null
+++ b/projects/hackc/expressions.py
@@ -0,0 +1,76 @@
+from .tokens import Token
+
+OPS = "+-*/&|<>="
+UNARY_OPS = "-~"
+CONSTANTS = ["true", "false", "null", "this"]
+
+
+class Term:
+ def __init__(self):
+ pass
+
+ @classmethod
+ def from_tokens(cls, tokens: list) -> tuple:
+ if not tokens:
+ return (None, 0)
+ if tokens[0].type in ["integer", "string"] or tokens[0] in CONSTANTS:
+ return (ConstantTerm(tokens[0]), 1)
+ if tokens[0] in UNARY_OPS:
+ term, dt = Term.from_tokens(tokens[1:])
+ return (UnaryTerm(tokens[0], term), dt + 1)
+
+
+class ConstantTerm:
+ def __init__(self, term: Token):
+ self.term = term
+
+
+class VarTerm:
+ def __init__(self, var: Token, subscript=None):
+ self.var = var
+ self.subscript = subscript
+
+
+class UnaryTerm:
+ def __init__(self, op: Token, term: Term):
+ self.op = op
+ self.term = term
+
+
+class SubroutineCall:
+ def __init__(self, name: Token, exprs: list):
+ self.name = name
+ self.exprs = exprs
+
+ @classmethod
+ def from_tokens(cls, tokens: list) -> tuple:
+ pass
+
+
+class Expression:
+ def __init__(self, lhs: Term, op=None, rhs=None):
+ self.lhs = lhs
+ self.op = op
+ self.rhs = rhs
+
+ @classmethod
+ def from_tokens(cls, tokens: list) -> tuple:
+ """Construct expression.
+
+ Format:
+ <term> (<op> <term>)?
+ """
+ lhs, dt = Term.from_tokens(tokens)
+ t = dt
+
+ op = tokens[t]
+ if op.token not in OPS:
+ return (Expression(lhs), t)
+
+ t += 1
+ rhs, dt = Term.from_tokens(tokens[t])
+ if rhs is None:
+ raise JSE(f"Expected other term, got `{rhs}` instead", rhs)
+ t += dt
+
+ return (Expression(lhs, op, rhs), t)