added write, read and for statements
This commit is contained in:
@@ -388,6 +388,42 @@ class IfStatement(Statement):
|
|||||||
if self.on_false:
|
if self.on_false:
|
||||||
self.on_false.eval(env)
|
self.on_false.eval(env)
|
||||||
|
|
||||||
|
class ReadStatement(Statement):
|
||||||
|
def __repr__(self):
|
||||||
|
return 'ReadStatement()'
|
||||||
|
|
||||||
|
def eval(self, env):
|
||||||
|
try:
|
||||||
|
return int(input())
|
||||||
|
except ValueError:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
class WriteStatement(Statement):
|
||||||
|
"""The AST node for write statements"""
|
||||||
|
def __init__(self, message):
|
||||||
|
"""
|
||||||
|
The initialization method.
|
||||||
|
|
||||||
|
message -- the message that should be printed
|
||||||
|
"""
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""
|
||||||
|
A representation of the node for debug purposes.
|
||||||
|
|
||||||
|
returns -- a String of the form
|
||||||
|
"WriteStatement(message)"
|
||||||
|
"""
|
||||||
|
return 'WriteStatement(%s)' % message
|
||||||
|
|
||||||
|
def eval(self, env):
|
||||||
|
"""
|
||||||
|
Evaluates the node. Prints the message.
|
||||||
|
|
||||||
|
returns -- None
|
||||||
|
"""
|
||||||
|
return print(self.message.eval(env))
|
||||||
|
|
||||||
class WhileStatement(Statement):
|
class WhileStatement(Statement):
|
||||||
"""The AST node for while statements"""
|
"""The AST node for while statements"""
|
||||||
@@ -420,3 +456,34 @@ class WhileStatement(Statement):
|
|||||||
"""
|
"""
|
||||||
while self.condition.eval(env):
|
while self.condition.eval(env):
|
||||||
self.body.eval(env)
|
self.body.eval(env)
|
||||||
|
|
||||||
|
class ForStatement(Statement):
|
||||||
|
"""The AST node for for statements"""
|
||||||
|
def __init__(self, count, body):
|
||||||
|
"""
|
||||||
|
The initialization method.
|
||||||
|
|
||||||
|
count -- the number of times the body should be executed
|
||||||
|
body -- the statement that is to be executed while
|
||||||
|
inside the loop
|
||||||
|
"""
|
||||||
|
self.count = count
|
||||||
|
self.body = body
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""
|
||||||
|
A representation of the node for debug purposes.
|
||||||
|
|
||||||
|
returns -- a String of the form
|
||||||
|
"ForStatement(count, body)"
|
||||||
|
"""
|
||||||
|
return 'ForStatement(%s, %s)' % (self.count, self.body)
|
||||||
|
|
||||||
|
def eval(self, env):
|
||||||
|
"""
|
||||||
|
Evaluates the node. Executes the body block count times.
|
||||||
|
|
||||||
|
env -- the environment in which to evaluate the node
|
||||||
|
"""
|
||||||
|
for _ in range(self.count.eval(env)):
|
||||||
|
self.body.eval(env)
|
||||||
|
@@ -117,13 +117,18 @@ def arithmetic_value():
|
|||||||
return ((num ^ (lambda i: IntArithmeticExp(i))) |
|
return ((num ^ (lambda i: IntArithmeticExp(i))) |
|
||||||
(imp_id ^ (lambda v: VarArithmeticExp(v))))
|
(imp_id ^ (lambda v: VarArithmeticExp(v))))
|
||||||
|
|
||||||
|
def read_statement():
|
||||||
|
def internal(parsed):
|
||||||
|
return ReadStatement()
|
||||||
|
return keyword('read') ^ internal
|
||||||
|
|
||||||
def arithmetic_term():
|
def arithmetic_term():
|
||||||
"""
|
"""
|
||||||
Matches an arithmetic term.
|
Matches an arithmetic term.
|
||||||
|
|
||||||
returns -- a parser matching an arithmetic value or group
|
returns -- a parser matching an arithmetic value or group
|
||||||
"""
|
"""
|
||||||
return arithmetic_value() | arithmetic_group()
|
return read_statement() | arithmetic_value() | arithmetic_group()
|
||||||
|
|
||||||
def arithmetic_exp():
|
def arithmetic_exp():
|
||||||
"""
|
"""
|
||||||
@@ -205,10 +210,44 @@ def while_statement():
|
|||||||
+ keyword('do') + Lazy(statements)
|
+ keyword('do') + Lazy(statements)
|
||||||
+ keyword('end') ^ internal)
|
+ keyword('end') ^ internal)
|
||||||
|
|
||||||
|
def for_statement():
|
||||||
|
"""
|
||||||
|
Builds a parser for for statements.
|
||||||
|
|
||||||
|
returns -- a parser for for statements
|
||||||
|
"""
|
||||||
|
def internal(parsed):
|
||||||
|
((((_, condition), _), body), _) = parsed
|
||||||
|
return ForStatement(condition, body)
|
||||||
|
return (keyword('for') + arithmetic_exp()
|
||||||
|
+ keyword('do') + Lazy(statements)
|
||||||
|
+ keyword('end') ^ internal)
|
||||||
|
|
||||||
|
def write_statement():
|
||||||
|
"""
|
||||||
|
Builds a parser for write statements.
|
||||||
|
|
||||||
|
returns -- a parser for write statements
|
||||||
|
"""
|
||||||
|
def internal(parsed):
|
||||||
|
(_, message) = parsed
|
||||||
|
return WriteStatement(message)
|
||||||
|
return keyword('write') + arithmetic_exp() ^ internal
|
||||||
|
|
||||||
def statement():
|
def statement():
|
||||||
return assign_statement() | if_statement() | while_statement()
|
"""
|
||||||
|
Builds a parser for single IMP statements.
|
||||||
|
|
||||||
|
returns -- a parser for single statements in the IMP langauge
|
||||||
|
"""
|
||||||
|
return write_statement() | assign_statement() | if_statement() | while_statement() | for_statement()
|
||||||
|
|
||||||
def statements():
|
def statements():
|
||||||
|
"""
|
||||||
|
Builds a parser for multiple IMP statements.
|
||||||
|
|
||||||
|
returns -- a parser for multiple statements in the IMP language
|
||||||
|
"""
|
||||||
sep = keyword(';') ^ (lambda x: lambda l, r: CompoundStatement(l, r))
|
sep = keyword(';') ^ (lambda x: lambda l, r: CompoundStatement(l, r))
|
||||||
return Exp(statement(), sep)
|
return Exp(statement(), sep)
|
||||||
|
|
||||||
|
@@ -23,6 +23,8 @@ TOKENS = [
|
|||||||
(r'>', RESERVED),
|
(r'>', RESERVED),
|
||||||
(r'=', RESERVED),
|
(r'=', RESERVED),
|
||||||
(r'!=', RESERVED),
|
(r'!=', RESERVED),
|
||||||
|
(r'read', RESERVED),
|
||||||
|
(r'write', RESERVED),
|
||||||
(r'and', RESERVED),
|
(r'and', RESERVED),
|
||||||
(r'or', RESERVED),
|
(r'or', RESERVED),
|
||||||
(r'not', RESERVED),
|
(r'not', RESERVED),
|
||||||
@@ -30,6 +32,7 @@ TOKENS = [
|
|||||||
(r'then', RESERVED),
|
(r'then', RESERVED),
|
||||||
(r'else', RESERVED),
|
(r'else', RESERVED),
|
||||||
(r'while', RESERVED),
|
(r'while', RESERVED),
|
||||||
|
(r'for', RESERVED),
|
||||||
(r'do', RESERVED),
|
(r'do', RESERVED),
|
||||||
(r'end', RESERVED),
|
(r'end', RESERVED),
|
||||||
(r'[0-9]+', INT),
|
(r'[0-9]+', INT),
|
||||||
|
Reference in New Issue
Block a user