<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,7 +1,10 @@
+SYMBOLS = ['do', 'defun', 'puts', 'printf', 'strlen']
 def is_list(l):
 	return type(l) == type([])
 def is_int(n):
 	return type(n) == type(1)
+def is_atom(a):
+	return a in SYMBOLS
 
 class Compiler:
 	
@@ -14,6 +17,8 @@ class Compiler:
 		self.PTR_SIZE = 4
 
 	def get_arg(self, a):
+		if is_atom(a):
+			return ['atom', a]
 		if is_int(a):
 			return ['int', a]
 		if is_list(a):
@@ -28,6 +33,20 @@ class Compiler:
 	
 	def defun(self, name, args, body):
 		self.global_functions[name] = [args, body]
+	
+	def ifelse(self, cond, if_branch, else_branch):
+		self.compile_exp(cond)
+		print(&quot;\ttestl\t%eax, %eax&quot;)
+		self.seq += 2
+		else_branch_seq = self.seq - 1
+		end_if_branch_seq = self.seq
+		print(&quot;\tje\t.L&quot; + str(else_branch_seq))
+		self.compile_exp(if_branch)
+		print(&quot;\tjmp\t.L&quot; + str(end_if_branch_seq))
+		print(&quot;.L&quot; + str(else_branch_seq) + &quot;:&quot;)
+		self.compile_exp(else_branch)
+		print(&quot;.L&quot; + str(end_if_branch_seq) + &quot;:&quot;)
+
 
 	def output_functions(self):
 		for name, data in self.global_functions.items():
@@ -47,39 +66,61 @@ class Compiler:
 			print(&quot;.LC&quot; + str(seq) + &quot;:&quot;)
 			print(&quot;\t.string \&quot;&quot; + str(c) + &quot;\&quot;&quot;)
 	
-	def compile_exp(self, exp):
-		if not exp or len(exp) == 0:
-			return False
-		if exp[0] == 'defun':
-			return self.defun(*exp[1:])
-		if exp[0] == 'do':
-			exp.pop(0)
-			map(self.compile_exp, exp)
-			return True
-				
-		call = str(exp[0])
-		stack_adjustment = self.PTR_SIZE + int(round((len(exp) - 1 + 0.5) * self.PTR_SIZE / (4.0 * self.PTR_SIZE))) * (4 * self.PTR_SIZE)
-		if exp[0] != 'do':
-			print(&quot;\tsubl\t$&quot; + str(stack_adjustment) + &quot;, %esp&quot;)
+	def compile_lambda(self, args, body):
+		name = &quot;lambda__&quot; + str(self.seq)
+		self.seq += 1
+		self.defun(name, args, body)
+		print(&quot;\tmovl\t$&quot; + str(name) + &quot;,%eax&quot;)
+		return ['subexpr']
+	
+	def compile_eval_arg(self, arg):
+		atype, aparam = self.get_arg(arg)
+		if atype == 'strconst':
+			return &quot;$.LC&quot; + str(aparam)
+		if atype == 'int':
+			return &quot;$&quot; + str(aparam)
+		if atype == 'atom':
+			return str(aparam)
+		return &quot;%eax&quot;
+	
+	def compile_call(self, func, args):
+		stack_adjustment = self.PTR_SIZE + int(round(((len(args) + 0.5) * self.PTR_SIZE / (4.0 * self.PTR_SIZE)))) * (4 * self.PTR_SIZE)
+		print(&quot;\tsubl\t$&quot; + str(stack_adjustment) + &quot;, %esp&quot;)
 		count = 0
-		for a in exp[1:]:
-			atype, aparam = self.get_arg(a)
-			if exp[0] != 'do':
-				if atype == 'strconst':
-					param = &quot;$.LC&quot; + str(aparam)
-				elif atype == 'int':
-					param = &quot;$&quot; + str(aparam)
-				else:
-					param = &quot;%eax&quot;
-				
+		for a in args:
+			param = self.compile_eval_arg(a)
 			if count &gt; 0:
-				i = count * self.PTR_SIZE
+				i = count * 4
 			else:
 				i = &quot;&quot;
-			print(&quot;\tmovl\t&quot; + str(param) + &quot;, &quot; + str(i) + &quot;(%esp)&quot;)
+			print(&quot;\tmovl\t&quot; + str(param)  + &quot;,&quot; + str(i) + &quot;(%esp)&quot;)
 			count += 1
-		print(&quot;\tcall\t&quot; + str(call))
+		res = self.compile_eval_arg(func)
+		if res == &quot;%eax&quot;:
+			res = &quot;*%eax&quot;
+		print(&quot;\tcall\t&quot; + str(res))
 		print(&quot;\taddl\t$&quot; + str(stack_adjustment) + &quot;, %esp&quot;)
+		return ['subexpr']
+	
+	def compile_do(self, exp):
+		map(self.compile_exp, exp)
+		return ['subexpr']
+
+	def compile_exp(self, exp):
+		if not exp or len(exp) == 0:
+			return False
+		if exp[0] == 'do':
+			self.compile_do(exp[1:])
+			return True
+		if exp[0] == 'defun':
+			return self.defun(*exp[1:])
+		if exp[0] == 'if':
+			return self.ifelse(*exp[1:])
+		if exp[0] == 'lambda':
+			return self.compile_lambda(*exp[1:])
+		if exp[0] == 'call':
+			return self.compile_call(exp[1], exp[2])
+		return self.compile_call(exp[0], exp[1:])
 
 	def compile_main(self, exp):
 		print(&quot;&quot;&quot;
@@ -108,14 +149,23 @@ main:
 	def compile(self, exp):
 		self.compile_main(['do', self.DO_BEFORE, exp, self.DO_AFTER])
 
-DO_BEFORE = ['do', 
-	['defun', 'hello_world', [], ['puts', &quot;Hello World&quot;]]
-]
+DO_BEFORE = []
 DO_AFTER = []
 
+&quot;&quot;&quot;
+prog = ['do',
+	['if', ['strlen',&quot;&quot;],
+		['puts', &quot;IF: The string was not empty&quot;],
+		['puts', &quot;ELSE: The string was empty&quot;]
+	],
+	['if', ['strlen',&quot;Test&quot;],
+		['puts', &quot;Second IF: The string was not empty&quot;],
+		['puts', &quot;Second IF: The string was empty&quot;]
+	]
+]
+&quot;&quot;&quot;
 prog = ['do',
-	['printf', &quot;'hello world' takes %ld bytes\\n&quot;, ['strlen', &quot;hello world&quot;]],
-	['printf', &quot;The above should show _%ld_ bytes\\n&quot;,11]
+	['call', ['lambda', [], [&quot;puts&quot;, &quot;Test&quot;]], [] ]
 ]
 
 compiler = Compiler(DO_BEFORE, DO_AFTER)</diff>
      <filename>pycompiler.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>3800f0d0363311610a91a68b3dcb217d421e7f2e</id>
    </parent>
  </parents>
  <author>
    <name>Michael Matuzak</name>
    <email>mmatuzak@gmail.com</email>
  </author>
  <url>http://github.com/emkay/pycompile/commit/8fac24d017e7605c81c7d6759547d0c1725e7881</url>
  <id>8fac24d017e7605c81c7d6759547d0c1725e7881</id>
  <committed-date>2009-05-02T13:52:02-07:00</committed-date>
  <authored-date>2009-05-02T13:52:02-07:00</authored-date>
  <message>adding lambdas. adding if branches. adding a symbol table.</message>
  <tree>5fe8a295877401b9b68ce6fee286f844f282cb5b</tree>
  <committer>
    <name>Michael Matuzak</name>
    <email>mmatuzak@gmail.com</email>
  </committer>
</commit>
