#!/usr/bin/python
""" fold_constants.py
Kelvie Wong
February 28, 2006
Generates C code where the constants are folded (stupid C doesn't do it
itself, because a function call to pow or sqrt is too complex for a
constant expression). Spits it all out to stdout, so pipe away."""
# TODO: arrays
# TODO: work on more than just floats?
# TODO: comments
import re, os, sys
from math import *
M_PI = pi
M_2_PI = 2/pi
M_PI_2 = pi/2
if __name__ == '__main__':
file = open(sys.argv[1])
expression = ''
prefix = ''
suffix = ''
vardict = {} # A dictionary to hold the variables needed by each other
for line in file:
# Find the assignment operator!
where = line.find('=')+1
# If there is an assignment operator or if this is a continued line
if where or expression:
# For now, ignore array declarations
if line.find('{') is not -1: # i.e. if it is found
print line.strip('\n')
continue
# What about comments?
# TODO: Eat comments, and place them on a separate line after (or
# inline? depending on how many cols left in the line)
#if line.find('/*') is not -1 and line.find('/*') < line.find('='):
# if the first assignment operator is commented...
#nextcomment = line.find('*/')
# No semicolon means that the expression continues on to the next
# line.
where2 = line.find(';')
if where2 is not -1: # is found
expression += line[where:where2]
newvalue = str(eval(expression, globals(), vardict))
# If there's a previous prefix (i.e. this is a continued line),
# use it, otherwise grab the prefix, prefix being the
# assignment expression. Same goes for the suffix.
prefix = prefix or line[0:where]
suffix = suffix or line[where2:-1]
# Output, as well, store the variable in the Python namespace;
# in case the variables are used later.
print '%s %s%s' % (prefix, newvalue, suffix)
varname = prefix.replace('const ', '')
varname = varname.replace('float ', '')
varname = varname.replace('static ', '')
varname = varname.strip('= \t')
vardict[varname] = float(newvalue)
prefix = ''
expression = ''
suffix = ''
else:
# Save the (incomplete) expression for later.
expression += line[where:line.rfind('\n')]
if not prefix:
prefix = line[0:where]
if not suffix:
suffix = line[where2:-1]
# If there isn't an assignment operator, just print the line.
else:
# print produces a newline anyways.
print line.strip('\n')