summaryrefslogtreecommitdiff
path: root/nandgame/assembler/py_nand_ass/lexer.py
diff options
context:
space:
mode:
authoruvok2026-01-14 20:44:16 +0100
committeruvok2026-01-14 20:44:16 +0100
commit1561eff8780dc15dc5ea46d7225cc49a46f709ca (patch)
tree130d44ef295ff2113fc56c592a78780035449dff /nandgame/assembler/py_nand_ass/lexer.py
parent281414ea9b42e213b85b95b7072b73d1f1e3f240 (diff)
Restructure asembler as package
Diffstat (limited to 'nandgame/assembler/py_nand_ass/lexer.py')
-rwxr-xr-xnandgame/assembler/py_nand_ass/lexer.py91
1 files changed, 91 insertions, 0 deletions
diff --git a/nandgame/assembler/py_nand_ass/lexer.py b/nandgame/assembler/py_nand_ass/lexer.py
new file mode 100755
index 0000000..e55ab05
--- /dev/null
+++ b/nandgame/assembler/py_nand_ass/lexer.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+
+import ply.lex as lex
+
+# List of token names. This is always required
+tokens = (
+ "OP",
+ "JUMP",
+ "COMMA",
+ "COLON",
+ "SYMBOL",
+ "NUMBER",
+ "HEXNUMBER",
+ "DOT",
+ "REG",
+ "NL",
+)
+
+# Regular expression rules for simple tokens
+t_COMMA = r","
+t_COLON = r":"
+t_DOT = r"\."
+
+
+def t_OP(t):
+ r"and|or|xor|not|mov|add|inc|sub|dec|cmp|neg|hlt|nop"
+ return t
+
+
+def t_REG(t):
+ r"\b(AD?M?|DM?|M|_)\b"
+ return t
+
+
+def t_JUMP(t):
+ r"jmp|jlt|jgt|jle|jge|jeq|jne"
+ return t
+
+
+def t_NUMBER(t):
+ r"\#\d+"
+ t.value = int(t.value[1:])
+ return t
+
+
+def t_HEXNUMBER(t):
+ r"\#0x[0-9a-fA-F]+"
+ t.value = int(t.value[1:], 16)
+ return t
+
+
+def t_SYMBOL(t):
+ r"[a-z][A-Za-z0-9_]+"
+ return t
+
+
+# Define a rule so we can track line numbers
+def t_NL(t):
+ r"\n+"
+ t.lexer.lineno += len(t.value)
+ return t
+
+
+# A string containing ignored characters (spaces and tabs)
+t_ignore = " \t"
+# t_ignore_COMMENT = r';.*'
+
+
+def t_COMMENT(t):
+ r";.*"
+ pass
+
+
+# Error handling rule
+def t_error(t):
+ print("!!! Illegal character '%s'" % t.value[0])
+ t.lexer.skip(1)
+
+
+# EOF handling rule
+def t_eof(t):
+ if not t.lexer.newline_added:
+ t.lexer.input("\n")
+ t.lexer.newline_added = True
+ return t.lexer.token()
+ return None
+
+
+# Build the lexer
+lexer = lex.lex()
+lexer.newline_added = False