add exponentation in the bitcode lexer

This commit is contained in:
Lephe 2019-10-08 22:32:27 +02:00
parent 14846e56ae
commit 053c1ebfaf
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
3 changed files with 67 additions and 34 deletions

View File

@ -78,7 +78,7 @@ AD P - - -
AE C - - -
C0 - Yes Yes Yes
C8 ⌋ - - -
C9 ^( - - -
C9 ^( Yes Yes -
CA [x]√( - - -
D0 ) Yes Yes Yes
D4 ⁻¹ - - -

View File

@ -63,6 +63,7 @@ class T(enum.IntEnum):
MINUS = 0xA7
STAR = 0xA8
SLASH = 0xA9
EXP = 0xC9
BANG = 0xD8
# Tokens with parameters

View File

@ -27,6 +27,11 @@ class Parser:
cond -> expr REL expr
expr -> factor | factor + expr | factor - expr
factor -> chunk | chunk * factor | chunk / factor
chunk -> power+
power -> atom | atom "^(" expr ")"
atom -> const | var | "(" expr ")" | FUN( funargs ")"
factor -> atom | atom * factor | atom / factor
atom -> const (var | "(" expr ")" | FUN funargs ")")* |
(var | "(" expr ")" | FUN funargs ")")+
@ -201,20 +206,20 @@ class Parser:
if t.type == T.MINUS:
f.append(Node(N.MINUS, self.factor()))
# factor -> atom | atom * factor | atom / factor
# factor -> chunk | chunk * factor | chunk / factor
def factor(self):
atom = self.atom()
chunk = self.chunk()
t = self.expect(T.STAR, T.SLASH, optional=True)
if t is None:
return atom
return chunk
if t.type == T.STAR:
return Node(N.MUL, atom, self.factor())
return Node(N.MUL, chunk, self.factor())
if t.type == T.SLASH:
return Node(N.DIV, atom, self.factor())
return Node(N.DIV, chunk, self.factor())
# atom -> const (VAR | "(" expr ")")* | (VAR | "(" expr ")")+
def atom(self):
# chunk -> power+
def chunk(self):
factors = []
# Initial sign
@ -224,37 +229,64 @@ class Parser:
self.expect(T.MINUS)
factors.append(Node(N.CONST, -1))
# Optional constant
if self.la.type == T.CONST:
factors.append(self.const())
while 1:
lat = self.la.type
if lat == T.VAR:
factors.append(self.var())
elif lat == T.LPAR:
self.expect(T.LPAR)
factors.append(self.expr())
# Allow a parenthesis to be removed at the end of a parameter
optional = (self.la.type == T.PARAM)
self.expect(T.RPAR, optional=optional)
elif lat == T.FUN:
name = self.expect(T.FUN).args[0]
a = self.funargs()
# Allow a parenthesis to be removed at the end of a parameter
optional = (self.la.type == T.PARAM)
self.expect(T.RPAR, optional=optional)
factors.append(Node(N.FUN, name, a))
else:
optional = len(factors) > 0
f = self.power(optional=optional)
if f is None:
break
factors.append(f)
return Node(N.MUL, *factors)
# power -> atom | atom "^(" expr ")"
def power(self, optional=False):
a = self.atom(optional=optional)
if a is None:
return None
if self.expect(T.EXP, optional=True) is not None:
e = self.expr()
# Allow a parenthesis to be removed at the end of a parameter
optional = (self.la.type == T.PARAM)
self.expect(T.RPAR, optional=optional)
return Node(N.EXP, a, e)
return a
# atom -> const | var | "(" expr ")" | FUN( funargs ")"
def atom(self, optional=False):
lat = self.la.type
if lat == T.CONST:
return self.const()
if lat == T.VAR:
return self.var()
if lat == T.LPAR:
self.expect(T.LPAR)
e = self.expr()
# Allow a parenthesis to be removed at the end of a parameter
optional = (self.la.type == T.PARAM)
self.expect(T.RPAR, optional=optional)
return e
if lat == T.FUN:
name = self.expect(T.FUN).args[0]
a = self.funargs()
# Allow a parenthesis to be removed at the end of a parameter
optional = (self.la.type == T.PARAM)
self.expect(T.RPAR, optional=optional)
return Node(N.FUN, name, a)
if not optional:
raise Exception("Empty atom")
return None
# funargs -> expr | expr; funargs
def funargs(self):
a = [self.expr()]