Skip to content

Commit

Permalink
llvm (#4)
Browse files Browse the repository at this point in the history
* Base llvm codegen + makefile to run it all

* update gitignore

* HotFix - print now works inside function

* Update float and int comportament

* Update float lexical

* HotFix on floatval

* Major repo reorganization
  • Loading branch information
VFermat authored Jun 2, 2021
1 parent 1dc670b commit 7cace6b
Show file tree
Hide file tree
Showing 22 changed files with 534 additions and 357 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@
test*
parser.out

/__pycache__
/__pycache__

output*
*.ll
*.dt
Empty file added compiler/__init__.py
Empty file.
Binary file added compiler/__pycache__/__init__.cpython-37.pyc
Binary file not shown.
Binary file added compiler/__pycache__/lexical.cpython-37.pyc
Binary file not shown.
Binary file added compiler/__pycache__/parser.cpython-37.pyc
Binary file not shown.
20 changes: 1 addition & 19 deletions lexical.py → compiler/lexical.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,10 @@ class DothLexer(Lexer):
# RETURN = r'(EZAT)'
# PRINT = r'(FREDRIK)'

NUMBER = r'\d+'
# @_(r'\d+')
# def NUMBER(self, t):
# t.value = int(t.value)
# return t

FLOAT = r'\d*\.?\d+'
# @_(r'\d*\.?\d+')
# def FLOAT(self, t):
# t.value = float(t.value)
# return t
NUMBER = r'\d+'

STRING = r'''("[^"\\]*(\\.[^"\\]*)*"|'[^'\\]*(\\.[^'\\]*)*')'''
# @_(r'''("[^"\\]*(\\.[^"\\]*)*"|'[^'\\]*(\\.[^'\\]*)*')''')
# def STRING(self, t):
# t.value = self.remove_quotes(t.value)
# return t

# def remove_quotes(self, text: str):
# if text.startswith('\"') or text.startswith('\''):
# return text[1:-1]
# return text

# Tokens
NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
Expand Down
57 changes: 42 additions & 15 deletions parser.py → compiler/parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import sys
sys.path.append('../')
from sly import Parser
from lexical import DothLexer
from nodes import Block, DefFuncOp, IfOp, LoopOp, DeclarationOp, AssignmentOp, ReturnOp, CallFunOp, PrintOp, BinOp, UnOp, IntVal, FloatVal, StringVal, BoolVal, IdentifierVal, NoOp
from compiler.lexical import DothLexer
from helpers.nodes import Node, Block, DefFuncOp, IfOp, LoopOp, DeclarationOp, AssignmentOp, ReturnOp, CallFunOp, PrintOp, BinOp, UnOp, IntVal, FloatVal, StringVal, BoolVal, IdentifierVal, NoOp
from llvmlite import ir


class DothParser(Parser):
Expand All @@ -11,10 +14,29 @@ class DothParser(Parser):
('left', TIMES, DIVIDE),
('right', UMINUS, UNOT, UPLUS),
)
debugfile = 'parser.out'
debugfile = './out/parser.out'

def __init__(self, debug=True):
def __init__(self, module, builder, printf, debug=True):
self.module = module
self.builder = builder
self.printf = printf
self.variables = {}
Node.module = self.module
Node.builder = self.builder
Node.printf = self.printf
Node.printfFmtArg = self._configurePrintf()

def _configurePrintf(self):
# Declare argument list
voidptrY = ir.IntType(8).as_pointer()
fmt = "%i \n\0"
cFmt = ir.Constant(ir.ArrayType(ir.IntType(8), len(fmt)),
bytearray(fmt.encode("utf8")))
globalFmt = ir.GlobalVariable(self.module, cFmt.type, name="fstr")
globalFmt.linkage = 'internal'
globalFmt.global_constant = True
globalFmt.initializer = cFmt
return globalFmt, voidptrY

@_('{ statement }')
def code(self, p):
Expand Down Expand Up @@ -62,14 +84,19 @@ def command(self, p):
return values[0]

@_(
'TSTRING NAME LPAREN param { param } RPAREN block EOL',
'TINT NAME LPAREN param { param } RPAREN block EOL',
'TFLOAT NAME LPAREN param { param } RPAREN block EOL',
'BOOL NAME LPAREN param { param } RPAREN block EOL',
'TSTRING NAME LPAREN { param } RPAREN block EOL',
'TINT NAME LPAREN { param } RPAREN block EOL',
'TFLOAT NAME LPAREN { param } RPAREN block EOL',
'BOOL NAME LPAREN { param } RPAREN block EOL',
'VOID NAME LPAREN { param } RPAREN block EOL',
)
def def_function(self, p):
values = p._slice
return DefFuncOp(values[1])
func = DefFuncOp(values[1], values[0])
for prm in p.param:
func.addParam(prm)
func.setBlock(p.block)
return func

@_(
'IF LPAREN or_expr RPAREN block elseif',
Expand All @@ -83,7 +110,7 @@ def conditional(self, p):
elif values[-1].type == 'elses':
root = IfOp(values[0], p.or_expr, p.block)
elses = p.elses
root.setElse(elses[3])
root.setElse(elses[2])
return root
elif values[-1].type == 'elseif':
root = IfOp(values[0], p.or_expr, p.block)
Expand Down Expand Up @@ -150,15 +177,15 @@ def assignment(self, p):
values = p._slice
return AssignmentOp(values[0], p.or_expr)

@_('RETURN or_expr')
@_('RETURN or_expr EOL')
def returns(self, p):
return ReturnOp(p.RETURN, p.or_expr)

@_(
'NAME LPAREN { param } RPAREN',
'NAME LPAREN { factor } RPAREN',
)
def call_function(self, p):
return CallFunOp(p.NAME)
return CallFunOp(p.NAME, p.factor)

@_('PRINT LPAREN or_expr RPAREN EOL')
def println(self, p):
Expand All @@ -172,7 +199,7 @@ def println(self, p):
)
def param(self, p):
values = p._slice
return (values[0], values[1])
return values[0], values[1]

@_('BOPEN { command } BCLOSE')
def block(self, p):
Expand Down Expand Up @@ -269,7 +296,7 @@ def factor(self, p):
if values[0].type == 'NUMBER':
return IntVal(values[0])
elif values[0].type in ['PLUS', 'MINUS', 'NOT']:
return UnOp(values[0], values[1])
return UnOp(values[0], values.factor)
elif values[0].type == 'NAME':
return IdentifierVal(values[0])
elif values[0].type == 'STRING':
Expand Down
Empty file added helpers/__init__.py
Empty file.
Binary file added helpers/__pycache__/__init__.cpython-37.pyc
Binary file not shown.
Binary file added helpers/__pycache__/nodes.cpython-37.pyc
Binary file not shown.
Binary file added helpers/__pycache__/symbolTable.cpython-37.pyc
Binary file not shown.
Loading

0 comments on commit 7cace6b

Please sign in to comment.