Skip to content

Commit

Permalink
yes! implemented parsing and lexing for function statements and
Browse files Browse the repository at this point in the history
function calls, including argument lists and parameter lists.
  • Loading branch information
amontalenti committed Jan 6, 2012
1 parent c26e5dd commit 2ba29c4
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 7 deletions.
33 changes: 33 additions & 0 deletions exprast.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,39 @@ class IfStatement(AST):
class WhileStatement(AST):
_fields = ['expr', 'truebranch']

class FuncStatement(AST):
_fields = ['name', 'returntype', 'parameters', 'expr']

class FuncParameterList(AST):
_fields = ['parameters']

def append(self,stmt):
self.parameters.append(stmt)

def __len__(self):
return len(self.parameters)

class FuncParameter(VarDeclaration):
pass

class FuncCall(AST):
_fields = ['name', 'arguments']

class FuncCallArguments(AST):
_fields = ['arguments']

def append(self,stmt):
self.arguments.append(stmt)

def __len__(self):
return len(self.arguments)

class FuncCallArgument(AST):
_fields = ['expr']

class ReturnStatement(AST):
_fields = ['expr']


# ----------------------------------------------------------------------
# DO NOT MODIFY ANYTHING BELOW HERE
Expand Down
7 changes: 4 additions & 3 deletions exprlex.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@

tokens = [
# keywords
'ID','CONST','VAR','PRINT', 'IF', 'ELSE', 'WHILE',
'ID','CONST','VAR','PRINT', 'IF', 'ELSE', 'WHILE', 'FUNC', 'RETURN',

# Operators and delimiters
'PLUS','MINUS','TIMES','DIVIDE',
'ASSIGN', 'SEMI', 'LPAREN', 'RPAREN',
'ASSIGN', 'SEMI', 'LPAREN', 'RPAREN', 'COMMA',

# Literals
'INTEGER', 'FLOAT', 'STRING', 'BOOL',
Expand Down Expand Up @@ -157,6 +157,7 @@
t_NOT = r'!'
t_LCURL = r'\{'
t_RCURL = r'\}'
t_COMMA = r','

# ----------------------------------------------------------------------
# *** YOU MUST COMPLETE : write the regexs and additional code below ***
Expand Down Expand Up @@ -272,7 +273,7 @@ def t_STRING(t):
# Match a raw identifier. Identifiers follow the same rules as Python.
# That is, they start with a letter or underscore (_) and can contain
# an arbitrary number of letters, digits, or underscores after that.
keywords = {"var", "const", "print", "if", "else", "while"}
keywords = {"var", "const", "print", "if", "else", "while", "func", "return"}
def t_ID(t):
r'[_A-Za-z][_A-Za-z0-9]*'
if t.value in keywords:
Expand Down
96 changes: 92 additions & 4 deletions exprparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,40 @@
| var_declaration
| assign_statement
| print_statement
| return_statement
if_statement : if expression { basicblock }
if_else_statement : if expression { basicblock } else { basicblock }
while_statement : while expression { basicblock }
const_declaration : CONST identifier = expression ;
const_declaration : const identifier = expression ;
var_declaration : VAR identifier typename ;
| VAR identifier typename = expression ;
var_declaration : var identifier typename ;
| var identifier typename = expression ;
assign_statement : location = expression ;
print_statement : PRINT expression ;
print_statement : print expression ;
return_statement : return expression ;
func_statement : func identifier ( parameters ) { basicblock }
parameter : identifier typename
parameters : parameters , parameter
| parameter
| empty
func_call : identifier ( arguments ) ;
arguments : arguments , argument
| argument
| empty
argument : expression
expression : + expression
| - expression
Expand Down Expand Up @@ -177,6 +196,9 @@ def p_statement(p):
| if_statement
| if_else_statement
| while_statement
| return_statement
| func_call
| func_statement
'''
p[0] = p[1]

Expand All @@ -198,6 +220,72 @@ def p_while_statement(p):
'''
p[0] = WhileStatement(p[2], p[4], lineno=p.lineno(1))

def p_func_call(p):
'''
func_call : ID LPAREN arguments RPAREN SEMI
'''
p[0] = FuncCall(p[1], p[3])

def p_arguments(p):
'''
arguments : argument
'''
p[0] = FuncCallArguments([p[1]])

def p_argument(p):
'''
argument : expression
'''
p[0] = p[1]

def p_arguments_1(p):
'''
arguments : arguments COMMA argument
| empty
'''
if p[1] is None:
return
p[0] = p[1]
p[0].append(p[3])


def p_parameter(p):
'''
parameter : ID typename
'''
# could support default argument values via 3rd
# argument here if we were feeling ambitious
# BTW, we're not :)
p[0] = FuncParameter(p[1], p[2], None)

def p_parameters(p):
'''
parameters : parameter
'''
p[0] = FuncParameterList([p[1]])

def p_parameters_1(p):
'''
parameters : parameters COMMA parameter
| empty
'''
if p[1] is None:
return
p[0] = p[1]
p[0].append(p[3])

def p_func_statement(p):
'''
func_statement : FUNC ID typename LPAREN parameters RPAREN LCURL basicblock RCURL
'''
p[0] = FuncStatement(p[2], p[3], p[5], p[8])

def p_return_statement(p):
'''
return_statement : RETURN expression SEMI
'''
p[0] = ReturnStatement(p[2], lineno=p.lineno(1))

def p_const_declaration(p):
'''
const_declaration : CONST ID ASSIGN expression SEMI
Expand Down
2 changes: 2 additions & 0 deletions tests/fnsimple.e
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
func foo int (arg1 int, arg2 int) { }
foo(1, 2);

0 comments on commit 2ba29c4

Please sign in to comment.