allow <sign><function> atoms

This commit is contained in:
Lephe 2019-10-06 10:57:58 +02:00
parent 7db38aac06
commit 9bf03c52be
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
6 changed files with 38 additions and 11 deletions

View File

@ -93,7 +93,10 @@ def main():
ast = parser.parse_program()
ast = ast.simplify()
print_ast(ast, lang="ast")
# Parser debug mode, print the AST
if debug == "parser":
print_ast(ast, lang="ast")
return 0
with Window(width=192, height=47, scale=scale, quiet=quiet) as w:
ctx = Context(w)

View File

@ -301,9 +301,10 @@ class TextLexer(LexerBase):
r"PRINT|STYLE|WAIT|REPEAT_END|REPEAT|WHILE_END|WHILE|IF_END|ELSE|"
r"IFELSE_END|IFELSE|IF",
re.IGNORECASE)
RE_CONST = re.compile(
r"([0-9]+(?:\.[0-9]+)?(?:[eE][0-9]+)?)(%?)")
RE_FUN = re.compile(
r"([a-zA-Z]+)\(")
def __init__(self, code):
"""Initialize the lexer with text code."""
@ -384,6 +385,13 @@ class TextLexer(LexerBase):
self.pending_param = True
return Token(T.CONST, f)
# Functions
m = re.match(self.RE_FUN, c)
if m is not None:
self.code = c[len(m[0]):]
self.pending_param = True
return Token(T.FUN, m[1])
# Variables
if c[0] in "MABCDEFxXyY":
var = c[0].lower() if c[0] in "xXyY" else c[0]
@ -391,11 +399,6 @@ class TextLexer(LexerBase):
self.pending_param = True
return Token(T.VAR, c[0])
# If nothing can be found, raise an exception
s = c.split(maxsplit=1)
err = s[0]
self.code = s[1] if len(s) > 1 else ""
# Comments
if c[0] == "#":
splits = c.split('\n', maxsplit=1)
@ -404,6 +407,11 @@ class TextLexer(LexerBase):
self.position -= 1
return self.lex()
# If nothing can be found, raise an exception
s = c.split(maxsplit=1)
err = s[0]
self.code = s[1] if len(s) > 1 else ""
raise Exception("Lexical error near '{}'".format(err))
def at_end(self):

View File

@ -215,10 +215,16 @@ class Parser:
# atom -> const (VAR | "(" expr ")")* | (VAR | "(" expr ")")+
def atom(self):
factors = []
lat = self.la.type
# Case of constants
if lat == T.PLUS or lat == T.MINUS or lat == T.CONST:
# Initial sign
if self.la.type == T.PLUS:
self.expect(T.PLUS)
elif self.la.type == T.MINUS:
self.expect(T.MINUS)
factors.append(Node(N.CONST, -1))
# Optional constant
if self.la.type == T.CONST:
factors.append(self.const())
while 1:

View File

@ -27,12 +27,14 @@ def runtest(program, refout=None, refimg=None):
success = True
if refout is not None:
with open(refout, "r") as fp:
with open(refout, "rb") as fp:
refout = fp.read()
if st.stdout == refout:
print(" Output is correct.")
else:
print(" -> Output is incorrect!")
print(" ref:", repr(refout))
print(" out:", repr(st.stdout))
success = False
if refimg is not None:

4
tests/function-atom.out Normal file
View File

@ -0,0 +1,4 @@
-2.0
1.0
1.0
-1.0

4
tests/function-atom.txt Normal file
View File

@ -0,0 +1,4 @@
print -2cos(0)
print 1cos(0)
print +cos(0)
print -cos(0)