('right', 'ABS', 'UPLUS')
)
-cards = []
+deck = []
scopes = []
targets = []
+untyped = []
# Program level
def p_card(t):
'card : TAB statement SEMI'
- cards.append((None, t[2]))
+ deck.append((None, t[2]))
def p_labeled_card(t):
'card : NAME TAB statement SEMI'
- cards.append((t[1], t[3]))
+ deck.append((t[1], t[3]))
# Statement level
def p_statement_substitution(t):
'statement : NAME EQUALS expression'
t[0] = ('substitution', t[1], t[3])
+ if t[1] not in untyped:
+ untyped.append(t[1])
# Expression parsing
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
+ print "Foo"
t[0] = (t[2].lower(), t[1], t[3])
def p_expression_binop2(t):
def p_expression_float(t):
'expression : FLOATNUM'
- t[0] = ('float', t[1])
+ t[0] = ('floatnum', t[1])
def p_expression_subscript(t):
'expression : NAME application'
import sys, re
-indent = 0
-
-def recode(cards):
- "Rewrite the statement list."
- # Find first INTEGER declaration, move it to the front.
- for statement in cards:
- if statement[1][0] == 'integer':
- declaration = statement
- cards.remove(declaration)
- cards = [declaration] + cards
- break
- return cards
+integers = []
+floats = []
+bools = []
+dimensions = {}
+
+def declare(var, lst):
+ if var in untyped:
+ untyped.remove(var)
+ lst.append(var)
+
+def analyze(deck):
+ "Gather variable types."
+ global integers, floats, bools
+ for (label, statement) in deck:
+ if statement[0] == 'integer':
+ print "Bar!", statement
+ for var in statement[1:]:
+ declare(var, integers)
+ elif statement[0] == 'dimension':
+ for (var, dimlist) in statement[1]:
+ dimensions[var] = dimlist
+ elif statement[0] == 'substitution':
+ var = statement[1]
+ if var not in integers + bools + floats + untyped:
+ untyped.append(var)
def print_expr(t):
if t[0] == 'variable':
return "(%s == %s)" % (print_expr(t[1]), print_expr(t[2]))
elif t[0] == 'ne':
return "(%s != %s)" % (print_expr(t[1]), print_expr(t[2]))
- elif t[0] == 'pow':
+ elif t[0] == 'p':
return "pow(%s, %s)" % (print_expr(t[1]), print_expr(t[2]))
elif t[0] == 'and':
return "(%s && %s)" % (print_expr(t[1]), print_expr(t[2]))
return "%s" % print_expr(t[1])
elif t[0] == '-':
return "(-%s)" % print_expr(t[1])
- elif t[0] == 'intnum':
+ elif t[0] in ('intnum', 'floatnum'):
return t[1]
else:
return "***"+`t`
def print_statement(statement):
- global indent
- if statement[0] == 'end_program':
- return "/* END OF PROGRAM */"
- elif statement[0] == 'dimension':
- declaration = "int";
- for (var, dimlist) in statement[1]:
- declaration += " " + var
- for dim in dimlist:
- declaration += "[" + dim[1] + "]"
- declaration += ", "
- return(declaration[:-2] + ";")
+ if statement[0] in ('dimension', 'end_program', 'integer'):
+ pass
elif statement[0] == 'for':
(keyword, label, dummy, start, increment, predicate) = statement
- indent += 1
return "for (%s = %s; %s; %s += %s) {" % (dummy, print_expr(start), print_expr(predicate), dummy, print_expr(increment))
+ elif statement[0] == 'goto':
+ return "goto " + statement[1] + ";"
elif statement[0] == 'if':
- return "if (" + print_expr(statement[1]) + ") " + print_statement(statement[2]) + ";"
- elif statement[0] == 'integer':
- return "int " + ", ".join(statement[1:]) + ";"
+ return "if (" + print_expr(statement[1]) + ") " + print_statement(statement[2])
elif statement[0] == 'substitution':
- return statement[1] + " = " + print_expr(statement[2])
+ return statement[1] + " = " + print_expr(statement[2]) + ";"
else:
return(`statement`)
source = sys.stdin.read()
# Grotty hack to add end-of-statement delimiters
source = re.sub("\n([A-Z]|\t)", " ;\n\\1", source).rstrip() + " ;\n"
- yacc.parse(source)
- cards = recode(cards)
+ yacc.parse(source, debug=1)
+
+ analyze(deck)
print "#include <math.h>"
print "main(int argc, char *argv[])"
print "{"
- for (label, statement) in cards:
+ if integers:
+ print "\tint " + ", ".join(integers) + ";\t/* INTEGER */"
+ if bools:
+ print "\tint " + ", ".join(bools) + ";\t/* boolean */"
+ if untyped:
+ print "\tint " + ", ".join(untyped) + ";\t/* untyped */"
+ if floats:
+ print "\tfloat " + ", ".join(floats) + ";"
+ indent = 0
+ for (label, statement) in deck:
if label in targets:
sys.stdout.write(label+":")
- sys.stdout.write("\t" + " "*indent +print_statement(statement) + "\n")
+ rep = print_statement(statement)
+ if rep:
+ sys.stdout.write("\t" + " "*indent + rep + "\n")
+ if rep[-1] == '{':
+ indent += 1
if label in scopes:
indent -= 1
print ("\t" + " "*indent) + "}"