view code/lmc.tp @ 1:68d1447bfdbe

Support for compiling lists, tuples and integer literals in lmc. Added small test lm program for exercising compiler.
author Michael Pavone <pavone@retrodev.com>
date Fri, 25 Jul 2014 09:13:09 -0700
parents 360862a3f3e3
children 71e8d638da5c
line wrap: on
line source

{
	_exprHandlers <- dict hash
	
	compileExpr <- :expr {
		_exprHandlers ifget: (expr nodeType) :handler {
			handler: expr
		} else: {
			print: "Unhandled node type " . (expr nodeType) . "\n"
		}
	}
	
	_exprHandlers set: (ast intlit) :expr {
		print: "  LDC " . (expr val) . "\n"
	}
	
	_exprHandlers set: (ast sequence) :expr {
		count <- 0
		foreach: (expr els) :idx el {
			compileExpr: el
			count <- count + 1
		}
		if: (expr array?) {
			count <- count - 1
		} else: {
			print: "  LDC 0\n"
		}
		while: { count > 0} do: {
			print: "  CONS\n"
			count <- count - 1
		}
	}
	#{
		compile <- :code {
			res <- parser top: code
			if: res {
				outer <- res yield
				main_fun <- false
				others <- dict hash
				foreach: (outer messages) :idx msg {
					if: ((msg to) name) = "main" {
						main_fun <- msg assign
					} else: {
						others set: ((msg to) name) (msg assign)
					}
				}
				foreach: (main_fun expressions) :idx expr {
					compileExpr: expr
				}
				foreach: others :name fun {
					print: ";" . name . "\n"
					foreach: (fun expressions) :idx expr {
						compileExpr: expr
					}
				}
			} else: {
				print: "Parse failed!\n"
			}
		}

		compileFile <- :filename {
			f <- file open: filename
			compile: (f readAll)
		}
		
		main <- :args {
			if: (args length) > 1 {
				compileFile: (args get: 1)
			} else: {
				print: "Usage lmc FILE\n"
			}
		}
	}
}