/python

Primary LanguageRacket

CHOSEN TESTS
	types/test_booleans.py
	types/test_div_zero.py
	types/test_floats.py
	
	scope/lambda1.py
	scope/lambda2.py
	scope/lambda4.py


STRUCTURE
	The code is structured mostly as the stencil had it laid out.
"get-structured-python" converts the parsed code into a PyExpr, which is then desugared by
"python-desugar", which also handles most of the scope features. The desugared expression
is given to "python-lib", which handles built-in python library functions, then "python-interp"
is used to interpret the function.
	Exceptions were done in a similar manner to ParselExtend, where a single data type
separates exceptions from values. Throughout the interpreter, an ExceptionA is automatically
percolated back up without continuing interpretation.

	Errors just shown with (error ...). parse-python does this, so we thought it would be
appropriate to use it elsewhere as well.



DESIGN
	CORE REPRESENTATION
	We decided to have a variant for each primitive type. This means we plan on
having a VInt for integers, a VFloat for floats, a VStr for strings, and so on. We
chose to do this because, either way, we thought we would have to do type checking
for operations anyways. Being able to separate each easily makes things easier to handle.
	
	SCOPE
		Scope is done mainly through desugaring. The desugar process finds
variable assignments and brings them to the top level, or the top of a function (or
lambda) definition, whichever is first. They are defined as VUndefined, and are replaced
by the assignments. If something tries to access a variable before it has been assigned,
it will receive "VUndefined", and will know it is unbound and an error should
be thrown.
		To show pythonic scope, assignments replace the "closest"
(as close to the current scope) variable declaration, but accesses search up the scopes
until it finds a defined variable. This allows scope closing over variable accesses, but
not assignments.
		The environment is a linked list, and the store is a hash set for ease
in simulating python's scope. If a new function scope is created, simply adding to
the environment means old variables are untouched. After the new scope ends, the outer
scope is also able to continue using its variables as if the new scope did not exist.
However, if the new scope tries to access a variable, then it is able to search through
outer scopes for the last defined.