Skip to content

Commit

Permalink
fixed: a.b+1 precedence is (a.b)+1
Browse files Browse the repository at this point in the history
  • Loading branch information
hoosierEE committed Jun 18, 2024
1 parent b05e266 commit 724850a
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 9 deletions.
17 changes: 8 additions & 9 deletions prototype/Parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ def _Parse(t:list,verbose:int)->Ast:
if not t: return
z,b,s,d = len(t),[],[],[]
noun = lambda x:type(x)==tuple or type(x)==str and x.replace('.','').replace('-','').isalnum()
# def noun(x:str) -> bool:
# return type(x)==tuple or type(x)==str and x.replace('.','').replace('-','').isalnum()

def debug(*args):#optional logging
if verbose<1: return
Expand All @@ -25,15 +23,15 @@ def err(i,m=''): return f'Parse: {m}{LF}{"".join(t[:i]).strip()}'
def reduce(until:str):#reduce until (until) matches
while s and str(s[-1].name) not in until: rt(*s.pop())

def rt(x,arity):#(r)educe (t)op of stack based on x's arity
def rt(x,arity):#(r)educe (t)op of stack based on x's arity (and precedence)
k = [d.pop() for _ in range(min(len(d),arity))][::-1]
if x in ENDEXP:
if len(k)>1 and k[1][0]==x: k = [k[0],*k[1][1]]
elif len(k)>0 and k[0][0]==x: k = [*k[0][1],*k[1:]]
# if x in ANDOR: d.append(Ast(x,*k))
if noun(x): d.append(Ast('app',Ast(x),*k))
elif type(x)==Ast and k: d.append(Ast('app',x,*k))
else: d.append(Ast(x,*k))
# if x in ANDOR: d.append(Ast(x,*k)) #TODO: (and;or) short-circuiting operators
if noun(x): d.append(Ast('app',Ast(x),*k))
elif type(x)==Ast and k: d.append(Ast('app',x,*k))
else: d.append(Ast(x,*k))
debug('rt',x,k)

def rp(x:Op):#(r)educe (p)aren, e.g: reduce(OPAREN); rp(s.pop())
Expand Down Expand Up @@ -97,12 +95,13 @@ def loop(i=0) -> int|None:#return index of error-causing token (if any), else No
else: s.append(Op(c,2))
elif c in VERBM:
if n in CPAREN+ENDEXP: raise SyntaxError(err(i,"can't project a prefix op"))
else: s.append(Op(c,1)); break
else: s.append(Op(c,1))
elif c in VERB:
if c!='.' and s and s[-1]==Op('.',2): reduce('')#precedence: a.b+1 == (a.b)+1
if n in CPAREN+ENDEXP: rq(Ast('prj',Ast(c),d.pop())); continue
else: s.append(Op(c,2))
else:
s.append(Op(d.pop(),1))#whatever this was, it wasn't a noun
s.append(Op(d.pop(),1))#top of d wasn't a noun after all
if noun(c) or c[0] in '`"': d.append(Ast(c)); continue
pad(n); s.append(Op(c,1))
break
Expand Down
1 change: 1 addition & 0 deletions prototype/Test.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def test_expr(scan,parse):
[x] ⇒ (prg x)
a.b.c ⇒ (. a (. b c))
a.b - 1 ⇒ (- (. a b) 1)
1 - a.b ⇒ (- 1 (. a b))
a ⇒ a
a(b) ⇒ (app a b)
a++b ⇒ (+ a (+ b))
Expand Down

0 comments on commit 724850a

Please sign in to comment.