Compare commits
6 Commits
482547fea9
...
23ef1f1228
Author | SHA1 | Date |
---|---|---|
Emi Simpson | 23ef1f1228 | |
Emi Simpson | 6a598e3856 | |
Emi Simpson | 2479dbd9a6 | |
Emi Simpson | 67a7bbc821 | |
Emi Simpson | a673db77ca | |
Emi Simpson | 656b44e18f |
|
@ -135,14 +135,6 @@ aka a let binding without an "in" clause
|
|||
["addTwo", {"x": ["S", ["S", "x"]]}]
|
||||
```
|
||||
|
||||
### Execute REPL within context
|
||||
|
||||
(this is still a bit buggy, and may create an invalid REPL)
|
||||
|
||||
```json
|
||||
[{"x": []}, 12]
|
||||
```
|
||||
|
||||
### Multi-argument functions
|
||||
|
||||
```json
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
[
|
||||
"fibb",
|
||||
"slow_fibb",
|
||||
{
|
||||
"0": 0,
|
||||
"1": 1,
|
||||
"n": ["+", ["slow_fibb", ["+", "n", -2]], ["slow_fibb", ["+", "n", -1]]]
|
||||
},
|
||||
|
||||
"fast_fibb",
|
||||
[
|
||||
"fibb_helper",
|
||||
{
|
||||
|
|
18
ir.py
18
ir.py
|
@ -11,6 +11,12 @@ import types_
|
|||
Expression: TypeAlias = 'MonoFunc | Application | Int | Variable | Builtin | LetBinding | ReplHole | Switch'
|
||||
Value: TypeAlias = 'MonoFunc | Int | Builtin | ReplHole'
|
||||
|
||||
dollar_count: int = 0
|
||||
def mk_dollar() -> str:
|
||||
global dollar_count
|
||||
dollar_count += 1
|
||||
return f'${dollar_count-1}'
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ReplHole:
|
||||
typ_bindings: types_.Context
|
||||
|
@ -34,7 +40,7 @@ class ReplHole:
|
|||
def render(self) -> str:
|
||||
return '\n'.join(
|
||||
f'const {var_name} = ({var_expr.codegen()});'
|
||||
for (var_name, var_expr) in self.val_bindings
|
||||
for (var_name, var_expr) in self.val_bindings[::-1]
|
||||
if var_name not in types_.BUILTINS_CONTEXT
|
||||
)
|
||||
|
||||
|
@ -120,18 +126,20 @@ class MonoFunc:
|
|||
case [(var, [])]: # Binds a single variable to the entire input
|
||||
return Ok(MonoFunc(var, body))
|
||||
|
||||
local_variable = mk_dollar()
|
||||
|
||||
# If those special cases fail, we eliminate the pattern matching to produce a
|
||||
# single body:
|
||||
match_trees = tuple( # Construct a match tree for each possible branch
|
||||
pattern.match_tree(
|
||||
EMPTY_STRUCT_PATH,
|
||||
LeafNode.from_value(bindings_to_lets(pattern.bindings(), Variable('$'), body))
|
||||
LeafNode.from_value(bindings_to_lets(pattern.bindings(), Variable(local_variable), body))
|
||||
)
|
||||
for (pattern, body) in forms
|
||||
)
|
||||
unified_match_tree = merge_all_trees(match_trees) # Unify all the trees
|
||||
compiled_tree = compile_tree(unified_match_tree, Variable('$')) # Turn each tree into IR
|
||||
return compiled_tree <= p(MonoFunc, '$')
|
||||
compiled_tree = compile_tree(unified_match_tree, Variable(local_variable)) # Turn each tree into IR
|
||||
return compiled_tree <= p(MonoFunc, local_variable)
|
||||
|
||||
def try_apply(self, v: Expression) -> Option[Expression]:
|
||||
return Some(self.body.subst(v, self.arg))
|
||||
|
@ -222,7 +230,7 @@ class Application:
|
|||
return unwrap_opt(self.first.try_apply(self.arg)).codegen()
|
||||
else:
|
||||
match self.first:
|
||||
case Application(Builtin(Builtin.BB_PLUS), addend1):
|
||||
case Application(Builtin(Builtin.BB_PLUS()), addend1):
|
||||
return f'({addend1.codegen()} + {self.arg.codegen()})'
|
||||
case Builtin(Builtin.BB_PLUS_CONST(n)):
|
||||
return f'({self.arg.codegen()}{n:+})'
|
||||
|
|
5
opt.py
5
opt.py
|
@ -10,8 +10,9 @@ Optimization: TypeAlias = Callable[[Expression], Option[Expression]]
|
|||
def eliminate_single_let(expr: Expression) -> Option[Expression]:
|
||||
match expr:
|
||||
case LetBinding(lhs, rhs, body):
|
||||
if count_uses(lhs, body) <= 1:
|
||||
# RHS is used at most once i nthe body
|
||||
rhs_is_simple = isinstance(rhs, Int | Variable | Builtin)
|
||||
if count_uses(lhs, body) <= 1 or rhs_is_simple:
|
||||
# RHS is used at most once i nthe body or replication wouldnt be costly
|
||||
if count_uses(lhs, rhs) > 0:
|
||||
# RHS is recursive
|
||||
if not isinstance(body, Variable):
|
||||
|
|
Loading…
Reference in New Issue