summaryrefslogtreecommitdiff
path: root/nandgame/assembler
diff options
context:
space:
mode:
Diffstat (limited to 'nandgame/assembler')
-rwxr-xr-xnandgame/assembler/parser.py89
-rw-r--r--nandgame/assembler/parsetypes.py11
2 files changed, 60 insertions, 40 deletions
diff --git a/nandgame/assembler/parser.py b/nandgame/assembler/parser.py
index 9e4bf45..a140eea 100755
--- a/nandgame/assembler/parser.py
+++ b/nandgame/assembler/parser.py
@@ -8,14 +8,9 @@ from ply.lex import LexToken
# Get the token map from the lexer. This is required.
from lexer import tokens
-# Error rule for syntax errors
-
+import parsetypes as pt
-def p_error(p: LexToken):
- if p:
- print(f"Unexpected {repr(p.value)} on line {p.lineno}")
- else:
- print("Unexpected end of file.")
+# Error rule for syntax errors
def p_program(p):
@@ -30,7 +25,7 @@ def p_empty(p):
pass
-def p_inss(p):
+def p_instructions(p):
"""instruction_list : instruction_list line
| line
"""
@@ -38,15 +33,11 @@ def p_inss(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
-
- # print(f"INSes: {len(p)}")
- # print(f" {p[1]}")
- # if len(p) > 2:
- # print(f" {p[2]}")
pass
-def p_inss2(p):
+# try right-recursive?
+def p_instructions2(p):
"""instruction_list2 : line instruction_list2
| line
"""
@@ -73,11 +64,11 @@ def p_line(p):
def p_instruction(p):
- """instruction : noarg
- | onearg
- | twoarg
+ """instruction : no_args
+ | two_arg
+ | three_arg
| jumpdest
- | invalid_arg
+ | one_arg_invalid
"""
print(f"Item: {p[1]}")
p[0] = p[1]
@@ -85,46 +76,57 @@ def p_instruction(p):
def p_jumpdest(p):
- """jumpdest : SYMBOL COLON"""
+ """jumpdest : symbol COLON"""
p[0] = (p[1],)
-def p_twoarg(p):
- """twoarg : op REG COMMA argument COMMA argument"""
- p[0] = (*p[1], p[2], p[4], p[6])
+def p_no_arg(p):
+ """no_args : opcode"""
+ p[0] = (*p[1], None, None, None)
pass
-def p_argument(p):
- """argument : number
- | REG
- | SYMBOL
- """
+def p_onearg_invalid(p):
+ """one_arg_invalid : opcode argument"""
+ print(f"Invalid number of arguments: {p[1:]}")
+ sys.exit(1)
pass
-def p_onearg(p):
- """onearg : op REG COMMA argument"""
+def p_two_arg(p):
+ """two_arg : opcode register COMMA argument"""
p[0] = (*p[1], p[2], p[4], None)
pass
-def p_noarg(p):
- """noarg : op"""
- p[0] = (*p[1], None, None, None)
+def p_three_arg(p):
+ """three_arg : opcode register COMMA argument COMMA argument"""
+ p[0] = (*p[1], p[2], p[4], p[6])
pass
-def p_invalid_arg(p):
- """invalid_arg : op argument"""
- print(f"Invalid opcode, destination missing: {p[1:]}")
- sys.exit(1)
- pass
+# checks which combinations are allowed is done one level up
+def p_argument(p):
+ """argument : number
+ | register
+ | symbol
+ """
+ p[0] = p[1]
+
+
+def p_symbol(p):
+ """symbol : SYMBOL"""
+ p[0] = pt.Symbol(p[1])
+
+def p_register(p):
+ """register : REG"""
+ p[0] = pt.Register(p[1])
-def p_op(p):
- """op : OP DOT JUMP
- | OP
+
+def p_opcode(p):
+ """opcode : OP DOT JUMP
+ | OP
"""
if len(p) == 2:
p[0] = (p[1], None)
@@ -139,4 +141,11 @@ def p_number(p):
p[0] = p[1]
+def p_error(p: LexToken):
+ if p:
+ print(f"Unexpected {repr(p.value)} on line {p.lineno}")
+ else:
+ print("Unexpected end of file.")
+
+
parser = yacc.yacc()
diff --git a/nandgame/assembler/parsetypes.py b/nandgame/assembler/parsetypes.py
new file mode 100644
index 0000000..4769e02
--- /dev/null
+++ b/nandgame/assembler/parsetypes.py
@@ -0,0 +1,11 @@
+from dataclasses import dataclass
+
+@dataclass
+class Symbol:
+ """Define a symbol"""
+ name: str
+
+@dataclass
+class Register:
+ """Define a source or dest register"""
+ name: str