allow <sign><function> atoms
This commit is contained in:
parent
7db38aac06
commit
9bf03c52be
5
fx92.py
5
fx92.py
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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:
|
||||
|
|
4
tests.py
4
tests.py
|
@ -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:
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
-2.0
|
||||
1.0
|
||||
1.0
|
||||
-1.0
|
|
@ -0,0 +1,4 @@
|
|||
print -2cos(0)
|
||||
print 1cos(0)
|
||||
print +cos(0)
|
||||
print -cos(0)
|
Loading…
Reference in New Issue