view src/bv.tp @ 3:dfc5f00c94bc

Initial evaluator implementation. fold is currently missing but other ops are present and seem to work
author Mike Pavone <pavone@retrodev.com>
date Thu, 08 Aug 2013 21:54:02 -0700
parents
children 538440e1c3d2
line wrap: on
line source

#{
	program <- {
		_input <- 0i64
		_zero <- #{
			string <- { "0" }
			eval <- { 0i64 }
		}

		_one <- #{
			string <- { "1" }
			eval <- { 1i64 }
		}

		_inputNode <- #{
			string <- { "input" }
			eval <- { _input }
		}
		#{
			plus <- :left right {
				#{
					string <- { "(plus " . (string: left) . " " . (string: right) . ")" }
					eval <- { (eval: left) + (eval: right)}
				}
			}
			zero <- {
				_zero
			}

			one <- {
				_one
			}

			opAnd <- :left right {
				#{
					string <- { "(and " . (string: left) . " " . (string: right) . ")" }
					eval <- { (eval: left) and (eval: right)}
				}
			}

			opOr <- :left right {
				#{
					string <- { "(or " . (string: left) . " " . (string: right) . ")" }
					eval <- { (eval: left) or (eval: right)}
				}
			}

			opXor <- :left right {
				#{
					string <- { "(xor " . (string: left) . " " . (string: right) . ")" }
					eval <- { (eval: left) xor (eval: right)}
				}
			}

			opNot <- :exp {
				#{
					string <- { "(not " . (string: exp) . ")" }
					eval <- { (eval: exp) xor -1 }
				}
			}

			shl1 <- :exp {
				#{
					string <- { "(shl1 " . (string: exp) . ")" }
					eval <- { lshift: (eval: exp) by: 1 }
				}
			}

			shr1 <- :exp {
				#{
					string <- { "(shr1 " . (string: exp) . ")" }
					eval <- { rshift: (eval: exp) by: 1 }
				}
			}

			shr4 <- :exp {
				#{
					string <- { "(shr4 " . (string: exp) . ")" }
					eval <- { rshift: (eval: exp) by: 4 }
				}
			}

			shr16 <- :exp {
				#{
					string <- { "(shr16 " . (string: exp) . ")" }
					eval <- { rshift: (eval: exp) by: 16 }
				}
			}

			input <- { _inputNode }

			if0:then:else <- :exp ifzero :ifnotzero {
				#{
					string <- { "(if0 " . (string: exp) . " " . (string: ifzero) . " " . (string: ifnotzero) . ")" }
					eval <- {
						if: (eval: exp) = 0i64 {
							eval: ifzero
						} else: {
							eval: ifnotzero
						}
					}
				}
			}

			run <- :in {
				_input <- in
				eval: root
			}

			root <- _zero

			string <- {
				"(lambda (input) " . (string: root) . ")"
			}

			gentestprog <- {
				root <- if0: (opAnd: input one) then: (
					plus: (opOr: input (shl1: one))
				) else: (
					opXor: input (shr16: input)
				)
				self
			}
		}
	}

	test <- {
		prog <- program gentestprog
		print: (string: prog) . "\n"
		vals <- #[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0x30001 0x50015]
		foreach: vals :idx val {
			print: "p(0x" . (hex: val) . ") = 0x" . (hex: (prog run: val)) . "\n"
		}
	}

	main <- {
		test:
	}
}