• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

A fast implementation of the Nix expression language


Commit MetaInfo

Revisión322ce0897c89057b54726d1d10da3deaa281ee57 (tree)
Tiempo2024-06-13 13:01:55
AutorCorbin <cds@corb...>
CommiterCorbin

Log Message

gmachine: Flesh out actual operations.

This is going to be a supercombinator machine, so I need to rethink the
current compilation scheme.

Cambiar Resumen

Diferencia incremental

--- a/gmachine.py
+++ b/gmachine.py
@@ -2,9 +2,15 @@
22 # We will implement graph reduction by compiling an expression into bytecode
33 # which, when evaluated, builds the graph node representing that expression.
44
5-CONST, OUTER, PICK = range(3)
5+# Quirks:
6+# 0) The instruction at PC 0 is always UNWIND, to ease EVAL.
7+
8+from heap import HeapApp
9+
10+OUTER, CONST, LOCAL, ARG, PRIM, MKAP, SLIDE, COND, EVAL, UNWIND = range(10)
611
712 class StackUnderflow(Exception): pass
13+class Overapplied(Exception): pass
814
915 class G(object):
1016 _immutable_attrs_ = "code[*]", "consts[*]"
@@ -14,25 +20,52 @@ class G(object):
1420
1521 def run(self, outers):
1622 stack = []
17- pc = 0
23+ dump = []
24+ # Quirk (0)
25+ pc = 1
1826 while pc < len(self.code):
1927 inst = self.code[pc]
2028 pc += 1
21- if inst == CONST:
22- stack.append(self.consts[self.code[pc]])
23- pc += 1
24- elif inst == OUTER:
29+ if inst == OUTER:
2530 stack.append(outers[self.code[pc]])
2631 pc += 1
27- elif inst == PICK:
28- depth = self.code[pc]
32+ elif inst == CONST:
33+ stack.append(self.consts[self.code[pc]])
34+ pc += 1
35+ elif inst == LOCAL:
36+ i = len(stack) - self.code[pc]
2937 pc += 1
30- i = len(stack) - depth
31- if i < 0: raise StackUnderflow()
3238 stack.append(stack[i])
39+ elif inst == ARG:
40+ i = len(stack) - self.code[pc]
41+ pc += 1
42+ node = stack[i]
43+ if not isinstance(node, HeapApp): raise Overapplied()
44+ stack.append(node.f)
45+ elif inst == PRIM: assert False
46+ elif inst == MKAP: stack.append(HeapApp(stack.pop(), stack.pop()))
47+ elif inst == SLIDE:
48+ top = stack.pop()
49+ stop = len(stack) - self.code[pc]
50+ pc += 1
51+ if stop < 0: raise StackUnderflow()
52+ del stack[:stop]
53+ stack.append(top)
54+ elif inst == COND: assert False
55+ elif inst == EVAL:
56+ top = stack.pop()
57+ dump.append((stack, pc))
58+ stack = [top]
59+ pc = 0
60+ elif inst == UNWIND:
61+ while isinstance(stack[-1], HeapApp): stack.append(stack[-1].f)
62+ # XXX supercombinators
63+ if dump: stack, pc = dump.pop()
64+ else: return stack.pop()
3365 else:
3466 print "Unknown bytecode:", inst
3567 assert False
68+ # XXX possible?
3669 try: return stack.pop()
3770 except IndexError: raise StackUnderflow()
3871
@@ -44,7 +77,8 @@ class MissingVar(Exception):
4477 class Compiler(object):
4578 def __init__(self, scope):
4679 self.scope = scope
47- self.code = []
80+ # Quirk (0)
81+ self.code = [UNWIND]
4882 self.consts = []
4983 self.locals = []
5084
@@ -62,9 +96,21 @@ class Compiler(object):
6296 self.code.append(CONST)
6397 self.code.append(i)
6498
65- def pick(self, i):
99+ def local(self, i):
100+ assert i >= 0, "implementation error"
101+ self.code.append(LOCAL)
102+ self.code.append(i)
103+
104+ def arg(self, i):
105+ assert i >= 0, "implementation error"
106+ self.code.append(ARG)
107+ self.code.append(i)
108+
109+ def mkAp(self): self.code.append(MKAP)
110+
111+ def slide(self, i):
66112 assert i >= 0, "implementation error"
67- self.code.append(PICK)
113+ self.code.append(SLIDE)
68114 self.code.append(i)
69115
70116 def finish(self): return G(self.code[:], self.consts[:])
--- a/heap.py
+++ b/heap.py
@@ -36,25 +36,25 @@ class HeapObject(object):
3636 self.__class__.__name__)
3737
3838 class HeapTrue(HeapObject):
39- _immutable_ = True
39+ # _immutable_ = True
4040 def asStr(self): return "true"
4141 def unwrapBool(self): return True
4242 true = HeapTrue()
4343
4444 class HeapFalse(HeapObject):
45- _immutable_ = True
45+ # _immutable_ = True
4646 def asStr(self): return "false"
4747 def unwrapBool(self): return False
4848 false = HeapFalse()
4949
5050 class HeapInt(HeapObject):
51- _immutable_ = True
51+ # _immutable_ = True
5252 def __init__(self, i): self.i = i
5353 def asStr(self): return str(self.i)
5454 def unwrapInt(self): return self.i
5555
5656 class HeapStr(HeapObject):
57- _immutable_ = True
57+ # _immutable_ = True
5858 def __init__(self, s): self.s = s
5959 def asStr(self): return self.s
6060 def unwrapStr(self): return self.s
--- a/main.py
+++ b/main.py
@@ -2,7 +2,7 @@ import sys
22
33 from gmachine import Compiler
44 from heap import defaultScope, InfiniteLoop
5-from parser import parse, MissingVar, NotAnExpr, ParseError
5+from parser import parse, NotAnExpr, ParseError
66
77 def entryPoint(argv):
88 if len(argv) < 2:
@@ -33,10 +33,6 @@ def entryPoint(argv):
3333 print "Error while compiling"
3434 print "Input syntax was not an expr, but:", e.cls
3535 return 1
36- except MissingVar as e:
37- print "Error while compiling"
38- print "Name was missing:", e.name
39- return 1
4036
4137 obj = g.run(defaultScope.values())
4238 print "Heap object:", obj
--- a/parser.py
+++ b/parser.py
@@ -161,12 +161,12 @@ class SelectBox(EBox):
161161 class VarBox(EBox):
162162 def __init__(self, name): self.name = name
163163 def pretty(self): return self.name
164- def compile(self, compiler):
165- # XXX should probably be a compiler method
166- if self.name in compiler.locals:
167- compiler.pick(len(compiler.locals) - compiler.locals.index(self.name))
168- elif self.name in compiler.scope: return compiler.outer(self.name)
169- else: raise MissingVar(self.name)
164+ # def compile(self, compiler):
165+ # # XXX should probably be a compiler method
166+ # if self.name in compiler.locals:
167+ # compiler.pick(len(compiler.locals) - compiler.locals.index(self.name))
168+ # elif self.name in compiler.scope: return compiler.outer(self.name)
169+ # else: raise MissingVar(self.name)
170170
171171 class AppBox(EBox):
172172 def __init__(self, func, arg):