Skip to content

Instantly share code, notes, and snippets.

@andydude
Created September 22, 2024 16:49
Show Gist options
  • Save andydude/7ba3c7444f4f666bc5a8d713e6cc0e73 to your computer and use it in GitHub Desktop.
Save andydude/7ba3c7444f4f666bc5a8d713e6cc0e73 to your computer and use it in GitHub Desktop.
Hex0 assembler, revised
# -*- mode: python; -*-
from dataclasses import dataclass
from enum import IntEnum
from functools import reduce
class Var(IntEnum):
SOF = -2
EOF = -1
WS = 0
COM = 2
HEX = 1
@dataclass
class Tok:
code: Var
text: str
def dfa_delta(c: str, state: Var) -> Var:
# comment state
if state == Var.COM:
if c == '\n':
return Var.WS
else:
return Var.COM
# normal states
if c in ' \t\n':
return Var.WS
elif c in '#;':
return Var.COM
elif c.isdigit():
return Var.HEX
elif c.isalpha() and c in "ABCDEFabcdef":
return Var.HEX
raise ValueError(c)
def yylex(yyinput):
def dfauto(tokens, ch):
# Give the previous state to the classifier
code = dfa_delta(ch, tokens[0].code)
return [Tok(code, ch)] + tokens
def pdauto(tokens, nt):
ot, otokens = tokens[0], tokens[1:]
# Merge tokens if the state is the same
ntokens = [Tok(ot.code, nt.text + ot.text)] \
if nt.code == ot.code else [nt, ot]
return ntokens + otokens
# Use DFA to classify chars
cls = reduce(dfauto, list(yyinput),
[Tok(Var.SOF, "\x02")])
# Use PDA to tokenize classes
tks = reduce(pdauto, cls,
[Tok(Var.EOF, "\x03")])
return tks[1:-1]
if __name__ == '__main__':
import sys
import binascii
binout = open("/dev/stdout", "wb")
tks = yylex(sys.stdin.read())
# Dump
for t in tks:
# print(repr(t))
if t.code is Var.HEX:
b = binascii.unhexlify(t.text)
binout.write(b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment