i think its ready
This commit is contained in:
parent
954ef31cd2
commit
75e3c031bf
6 changed files with 24 additions and 39 deletions
22
README.md
22
README.md
|
@ -1,5 +1,19 @@
|
||||||
# Todo
|
# CPQ
|
||||||
|
|
||||||
- [ ] Error handling(so it wont just print sly: unexpected token or whatever it says)
|
cpq.py compiles a cpl source file (.ou) into a quad ir file (.qud) using sly as the lexer and parser.
|
||||||
- [ ] Proper readme about files
|
|
||||||
- [x] Make cpq.py act as a cmd util - get input and output and such
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
python cpq.py source_file.ou
|
||||||
|
```
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
The compiler is seperated into multiple files:
|
||||||
|
|
||||||
|
- helper.py: contains a helper function (print_err)
|
||||||
|
- items.py: contains data structs for the parser
|
||||||
|
- lexer.py: lexer class
|
||||||
|
- parser.py: parser class
|
||||||
|
- cpq.py: main program and cmd handling logic
|
6
cpq.py
6
cpq.py
|
@ -8,13 +8,15 @@ from lexer import Lexer
|
||||||
from parser import Parser
|
from parser import Parser
|
||||||
from helper import print_err
|
from helper import print_err
|
||||||
|
|
||||||
|
# print signature
|
||||||
print_err('Aviv Romem')
|
print_err('Aviv Romem')
|
||||||
|
|
||||||
|
# invalid usage
|
||||||
if len(sys.argv) != 2 or not sys.argv[1].endswith('.ou'):
|
if len(sys.argv) != 2 or not sys.argv[1].endswith('.ou'):
|
||||||
print('USAGE: python cpq.py <file-name>.ou')
|
print('USAGE: python cpq.py <file-name>.ou')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
# load file and parser
|
||||||
file = sys.argv[1]
|
file = sys.argv[1]
|
||||||
output = file[:-3] + '.qud'
|
output = file[:-3] + '.qud'
|
||||||
f = open(file, 'r')
|
f = open(file, 'r')
|
||||||
|
@ -24,7 +26,7 @@ lexer = Lexer()
|
||||||
parser = Parser()
|
parser = Parser()
|
||||||
|
|
||||||
file = sys.argv[1]
|
file = sys.argv[1]
|
||||||
|
# parse and write file if valid
|
||||||
parser.parse(lexer.tokenize(text))
|
parser.parse(lexer.tokenize(text))
|
||||||
if not parser.had_errors:
|
if not parser.had_errors:
|
||||||
f = open(output, 'w')
|
f = open(output, 'w')
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def print_err(*args, **kwargs):
|
def print_err(*args, **kwargs):
|
||||||
|
''' print to stderr '''
|
||||||
print(*args, file=sys.stderr, **kwargs)
|
print(*args, file=sys.stderr, **kwargs)
|
2
lexer.py
2
lexer.py
|
@ -44,5 +44,5 @@ class Lexer(sly.Lexer):
|
||||||
self.lineno += t.value.count('\n')
|
self.lineno += t.value.count('\n')
|
||||||
|
|
||||||
def error(self, t):
|
def error(self, t):
|
||||||
print(f"Error at line {self.lineno}: unexpect character {t.value[0]}")
|
print(f"Error at line {self.lineno}: Unexpected character {t.value[0]}")
|
||||||
self.index += 1
|
self.index += 1
|
|
@ -6,9 +6,6 @@ from items import *
|
||||||
# Notes from reading:
|
# Notes from reading:
|
||||||
# - it seems no scoping is needed, as it contains only one scope per program
|
# - it seems no scoping is needed, as it contains only one scope per program
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Parser(sly.Parser):
|
class Parser(sly.Parser):
|
||||||
tokens = Lexer.tokens
|
tokens = Lexer.tokens
|
||||||
symbol_table = {}
|
symbol_table = {}
|
||||||
|
|
29
test.qud
29
test.qud
|
@ -1,29 +0,0 @@
|
||||||
ILSS t_1 a 10
|
|
||||||
JMPZ 15 t_1
|
|
||||||
IADD t_2 a 1
|
|
||||||
IASN a t_2
|
|
||||||
ILSS t_3 a 6
|
|
||||||
IEQL t_3 t_3 0
|
|
||||||
IEQL t_4 a 5
|
|
||||||
IADD t_5 t_3 t_4
|
|
||||||
JMPZ 12 t_5
|
|
||||||
JUMP 15
|
|
||||||
JUMP 14
|
|
||||||
IADD t_6 a 0
|
|
||||||
IASN a t_6
|
|
||||||
JUMP 1
|
|
||||||
IPRT a
|
|
||||||
IMLT t_7 a 5
|
|
||||||
IEQL t_8 t_7 1
|
|
||||||
JMPZ 22 t_8
|
|
||||||
IASN a 5
|
|
||||||
JUMP 27
|
|
||||||
JUMP 24
|
|
||||||
IEQL t_8 t_7 5
|
|
||||||
JMPZ 26 t_8
|
|
||||||
IPRT a
|
|
||||||
JUMP 26
|
|
||||||
JUMP 27
|
|
||||||
IPRT a
|
|
||||||
HALT
|
|
||||||
Aviv Romem
|
|
Loading…
Reference in a new issue