Skip to content

Commit

Permalink
simplify 'cmp' to... nothing
Browse files Browse the repository at this point in the history
  • Loading branch information
hoosierEE committed Aug 7, 2024
1 parent 0ad1a46 commit d272492
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 52 deletions.
29 changes: 14 additions & 15 deletions proto2/Parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@
from collections import namedtuple
Op = namedtuple('Op','name arity')

def repr_ast(s):
def repr_ast(s) -> str:
match s:
case '{': return 'λ'
case '(': return '⋯'
# case ('{',(('[',a),b)): return f'(λ ({repr_ast(a)}) {repr_ast(b)})'
case str(): return s
case a,None: return repr_ast(a)
case a,(): return repr_ast(a)
case '(',a: return f'(⋯ {repr_ast(a)})'
case '{',a: return f'(λ {repr_ast(a)})'
case 'vec',a: return f'(vec {" ".join(repr_ast(x) for x in a)})'
case str() as a,b: return f'({a} {repr_ast(b)})' if b else a
case tuple()|list(): return " ".join(map(repr_ast,s))
return repr(s)
case (a,None|()): return repr_ast(a)
case Ast(): return f'({repr_ast(s.n)} {repr_ast(s.c)})' # if s.c else repr_ast(s.n)
case tuple(): return " ".join(map(repr_ast,s))
return 42

class Ast(namedtuple('Ast','n c',defaults=(None,))):
def __repr__(s): return repr_ast(s)
Expand Down Expand Up @@ -65,7 +64,8 @@ def rp(x:Op):#(r)educe (p)aren, e.g: reduce(OPAREN); rp(s.pop())
def rq(k:Ast):#juxtaposition-based syntax: projection and composition
while s and str(s[-1].name) not in OPAREN+ENDEXP:
x,a = s.pop()
k = Ast('cmp',(Ast('prj',(Ast(x),d.pop())),k) if a==2 else Ast(Ast(x),k))
k = Ast((Ast('prj',(Ast(x),d.pop())) if a==2 else Ast(x)), k)
# k = Ast('cmp',(Ast('prj',(Ast(x),d.pop())),k) if a==2 else Ast(Ast(x),k))
d.append(k); debug('rq')

def loop(i=0) -> int|None:#return index of error-causing token (if any), else None
Expand Down Expand Up @@ -96,24 +96,23 @@ def loop(i=0) -> int|None:#return index of error-causing token (if any), else No
if i>=z: return
c,i,n = t[i],i+1,nn(i); debug(c,'↔',n or 'END')
if balance(c): return i
# if type(c)==tuple: d.append(Ast('vec',list(map(Ast,c)))); continue
if c in WHITESPACE and n=='/': return
if c in WHITESPACE: continue
if c in ENDEXP: reduce(OPAREN); pad(n); s.append(Op(';',2))
elif c in OPAREN: c in "({" and s.append(Op(d.pop(),1)); pad(n); s.append(Op(c,2))
elif c in CPAREN:
reduce(OPAREN); rp(x:=s.pop())
if s and s[-1].name=='{' and x.name=='[' and n!='}':
print('rp binary',s,d)
s.append(Op(';',2))
if s and s[-1].name=='{' and x.name=='[' and n!='}': s.append(Op(';',2))
else: continue
elif c in ADVERB:
k = Ast(c,d.pop())#bind adverb to whatever
while n in ADVERB: k,i,n = Ast(n,k),i+1,nn(i)
if s:
debug('adverb')
if not noun(str(s[-1].name)): s.append(Op(k,1))
else: d.append(Ast(s.pop().name)); s.append(Op(k,2))
else:
d.append(s.pop().name)
s.append(Op(k,2))
else: s.append(Op(k,1))
if s[-1].arity==2: pad(n)
elif c in ASSIGN:
Expand Down
34 changes: 6 additions & 28 deletions proto2/Semantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,45 +50,23 @@ def lamp(a:Ast) -> Ast:
case 'prj',(x,y): return Ast('{',(Ast('[',px),Ast(x.n,(y,px))))
case _: return Ast(lamp(a.n),tuple(map(lamp,a.c))) if a.c else Ast(a.n)

def lamc(a:Ast) -> Ast:
'''merge compositions into inner lambda'''
match a.n:
case 'cmp': # exactly 2 children
match a.c[0].n, a.c[1].n:
case '{','{':
b1 = a.c[0].c[1]
args,b2 = a.c[1].c
return Ast('{',args,Ast(b1.n,b1.c[0],b2))
case b,'{':
args,b2 = a.c[1].c
return Ast('{',args,Ast(a.c[0].n,b2))
case '{',b: return lamc(Ast('cmp',a.c[0],(lamc(a.c[1]))))
case b,c: return lamc(Ast('cmp',*map(lamc,a.c))) #lamc(a.c[0]),lamc(a.c[1])))
case _: return Ast(a.n,tuple(map(lamc,a.c))) if a.c else Ast(a.n)

def get_params(a:Ast) -> str:
'''get x y z arguments from lambdas'''
print(a)
match a:
case None: return ''
case ('x'|'y'|'z',None): return a.n
case (':'|'::',(b,c)) if b.n in ('x','y','z'): return get_params(c)
case tuple(): print(type(a)); return ''.join(map(get_params,a))
case (_,b): return ''.join(map(get_params,b)) if b else ''
case str()|None: return ''
case tuple(): return ''.join(map(get_params,a))
case _: return get_params(a.n)+get_params(a.c)

def formalize(a:Ast) -> Ast:
'''add formal arguments to lambdas'''
# (λ body) ⇒ args = get_params(body); return (λ (args) formalize(body))
# (λ ([ args...) body) ⇒ recurse on body
match a:
case ('{',(body,)): return Ast('{',(Ast('[',get_params(body)), formalize(body)))
case ('{',(('[',args),body)): return Ast('{',(Ast('[',args), formalize(body)))
case ('{',seq):
print('seq',seq)
# return Ast('{',(Ast('[',''.join(map(get_params,seq))), formalize(seq)))
return Ast('{',(Ast('[',get_params(seq)), formalize(seq)))
case b,tuple() as c:return Ast(formalize(b),tuple(map(formalize,c)))
case b,c: return Ast(formalize(b),formalize(c))
case ('{',tuple() as c): return Ast('{',(Ast('[',tuple(map(Ast,get_params(c)))), formalize(c)))
case (b,tuple() as c):return Ast(formalize(b),tuple(map(formalize,c)))
case (b,c): return Ast(formalize(b),formalize(c))
case _: return a

def Sema(a:Ast) -> Ast|Val:
Expand Down
18 changes: 9 additions & 9 deletions proto2/Test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,28 @@ def test_expr(scan,parse):
# projection/composition/application
#
a+ ⇒ (prj + a)
+- ⇒ (cmp + (prj -))
+- ⇒ (+ (prj -))
(+)- ⇒ (prj - +)
+(-) ⇒ (+ -)
a:b ⇒ (: a b)
(a:)2 ⇒ (app (prj : a) 2)
(-+:) ⇒ (cmp - (prj +:))
-+: ⇒ (cmp - (prj +:))
(-+:) ⇒ (- (prj +:))
-+: ⇒ (- (prj +:))
a::b ⇒ (:: a b)
a:f/y ⇒ (: a (app (/ f) y))
1 2+ ⇒ (prj + (vec 1 2))
1 2+3 4 ⇒ (+ (vec 1 2) (vec 3 4))
1 2+``a ⇒ (+ (vec 1 2) (vec ` `a))
a b 1 2 ⇒ (app a (app b (vec 1 2)))
1 2 a 3 4 ⇒ (app (vec 1 2) (app a (vec 3 4)))
a+- ⇒ (cmp (prj + a) (prj -))
*a+- ⇒ (cmp * (cmp (prj + a) (prj -)))
+-* ⇒ (cmp + (cmp - (prj *)))
a+- ⇒ ((prj + a) (prj -))
*a+- ⇒ (* ((prj + a) (prj -)))
+-* ⇒ (+ (- (prj *)))
a+; ⇒ (; (prj + a) ∅)
(+-)/y ⇒ (app (/ (cmp + (prj -))) y)
(+-)/y ⇒ (app (/ (+ (prj -))) y)
(2+)/y ⇒ (app (/ (prj + 2)) y)
x(+-)/y ⇒ (app (/ (cmp + (prj -))) x y)
x(+-*)/y ⇒ (app (/ (cmp + (cmp - (prj *)))) x y)
x(+-)/y ⇒ (app (/ (+ (prj -))) x y)
x(+-*)/y ⇒ (app (/ (+ (- (prj *)))) x y)
x(2+)/y ⇒ (app (/ (prj + 2)) x y)
() ⇒ (⋯ ∅)
()/y ⇒ (app (/ (⋯ ∅)) y)
Expand Down

0 comments on commit d272492

Please sign in to comment.