summaryrefslogtreecommitdiff
path: root/projects/hackc
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@fkfd.me>2022-08-29 22:59:56 +0800
committerFrederick Yin <fkfd@fkfd.me>2022-08-29 22:59:56 +0800
commitd303447dc7a830489828be2e66ccf8c36af4aed6 (patch)
tree53c02938a9b85ff94a5621371faa360f5630a6d8 /projects/hackc
parent7f54baf2668a58f2908f8242b2fbafc65a7f684a (diff)
hackc: backslash escape extension
Diffstat (limited to 'projects/hackc')
-rw-r--r--projects/hackc/__main__.py13
-rw-r--r--projects/hackc/parser.py5
-rw-r--r--projects/hackc/tokens.py8
3 files changed, 19 insertions, 7 deletions
diff --git a/projects/hackc/__main__.py b/projects/hackc/__main__.py
index a7bc06f..1cb5c3f 100644
--- a/projects/hackc/__main__.py
+++ b/projects/hackc/__main__.py
@@ -4,7 +4,7 @@ import os
from .parser import Parser
-def compile_jack(input_path: Path, verbose: bool):
+def compile_jack(input_path: Path, extensions: list, verbose: bool):
try:
filenames = os.listdir(input_path)
files = [Path(input_path / f) for f in filenames]
@@ -16,7 +16,7 @@ def compile_jack(input_path: Path, verbose: bool):
return
for input_fn in jack_files:
- parser = Parser(input_fn)
+ parser = Parser(input_fn, extensions=extensions)
parser.tokenize()
parser.print_tokens()
@@ -24,6 +24,13 @@ def compile_jack(input_path: Path, verbose: bool):
if __name__ == "__main__":
parser = ArgumentParser("hackc")
parser.add_argument("-v", "--verbose", action="store_true", help="verbose mode")
+ parser.add_argument(
+ "-E",
+ "--extension",
+ metavar="extension",
+ action="append",
+ help="enable extension of standard Jack",
+ )
parser.add_argument("input_path", help="Jack file or directory")
args = parser.parse_args()
- compile_jack(Path(args.input_path), args.verbose)
+ compile_jack(Path(args.input_path), args.extension or [], args.verbose)
diff --git a/projects/hackc/parser.py b/projects/hackc/parser.py
index 400b096..f73c3d1 100644
--- a/projects/hackc/parser.py
+++ b/projects/hackc/parser.py
@@ -29,8 +29,9 @@ SYMBOLS = "{}()[].,;+-*/&|<>=~"
class Parser:
- def __init__(self, fp):
+ def __init__(self, fp, extensions=[]):
self._fp = fp
+ self._extensions = extensions
self.tokens = []
def print_tokens(self):
@@ -80,7 +81,7 @@ class Parser:
break
rem = line[pos:] # remainder of line
- token = Token.from_line(rem, line_no, pos)
+ token = Token.from_line(rem, line_no, pos, extensions=self._extensions)
if token is not None:
self.tokens.append(token)
pos += token.length()
diff --git a/projects/hackc/tokens.py b/projects/hackc/tokens.py
index 7ae37ce..50c4173 100644
--- a/projects/hackc/tokens.py
+++ b/projects/hackc/tokens.py
@@ -35,7 +35,7 @@ class Token:
self.column = column
@classmethod
- def from_line(cls, line: str, line_no: int, column: int):
+ def from_line(cls, line: str, line_no: int, column: int, extensions=[]):
"""Extract first token from line and return it as an instance of Token."""
if not line:
return None
@@ -47,7 +47,11 @@ class Token:
if int_match is not None:
return Token("integer", int_match.group(1), line_no, column)
- str_match = re.match('(".*")', line)
+ if "escape" in extensions:
+ str_match = re.match(r'("(.|\\")+?[^\\]")', line)
+ else:
+ str_match = re.match('(".*?")', line)
+
if str_match is not None:
return Token("string", str_match.group(1), line_no, column)