Created
September 12, 2013 20:20
-
-
Save joyjding/6543190 to your computer and use it in GitHub Desktop.
Example class 1 from Spot language: If/Else If/Else
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class IfTheConditionTok(Token): | |
"""If the condition x>4 is equal to true, follow these instructions:{}. | |
Else if the condition x<4 is equal to true, follow these instructions:{}. | |
Else, follow these instructions: {}.""" | |
def __init__(self, value = 0): | |
self.value = value | |
self.labelno = None | |
self.condition = None | |
self.true_block = None | |
self.elseif_label = None | |
self.elseif_cond = None | |
self.elseif_block = None | |
self.else_label = None | |
self.else_block = None | |
def statementd(self): | |
global if_count | |
advance(IfTheConditionTok) | |
new_if_no = if_count | |
self.labelno = "%d" %new_if_no | |
if_count += 1 | |
new_condition = statement() | |
self.condition = new_condition | |
advance(CommaTok) | |
advance(FollowTheseInstructionsTok) | |
advance(ColonTok) | |
advance(LCurlyTok) | |
new_block = parse_block() | |
self.true_block = new_block | |
advance(RCurlyTok) | |
advance(PeriodTok) | |
if isinstance(token, ElseIfTok): | |
advance(ElseIfTok) | |
self.elseif_label = "elseif_%d" % new_if_no | |
new_condition = statement() | |
self.elseif_cond = new_condition | |
advance(CommaTok) | |
advance(FollowTheseInstructionsTok) | |
advance(ColonTok) | |
advance(LCurlyTok) | |
new_block = parse_block() | |
self.elseif_block = new_block | |
advance(RCurlyTok) | |
advance(PeriodTok) | |
if isinstance(token, ElseTok): | |
advance(ElseTok) | |
self.else_label = "else_%d" %new_if_no | |
advance(CommaTok) | |
advance(FollowTheseInstructionsTok) | |
advance(ColonTok) | |
advance(LCurlyTok) | |
else_block = parse_block() | |
self.else_block = else_block | |
advance(RCurlyTok) | |
advance(PeriodTok) | |
return self | |
def eval(self, env): | |
if self.condition.eval(env) == True: | |
print "\n>> The if condition is true -->executing if block" | |
for statement in self.true_block: | |
statement.eval(env) | |
elif self.condition.eval(env) == False: | |
print "\n>> The if condition is not true-->looking for else if or else" | |
if (self.elseif_cond.eval(env) == True and self.elseif_block != None): | |
print "\n>> Else if condition is true-->executing else if block" | |
for statement in self.elseif_block: | |
statement.eval(env) | |
if (self.elseif_cond.eval(env) == False and self.else_block != None): | |
print "\n>> The else if condition is not true-->executing else block" | |
for statement in self.else_block: | |
statement.eval(env) | |
if (self.elseif_block == None and self.else_block != None): | |
print "\n>> Previous conditions were not true-->Executing the else condition" | |
for statement in self.else_block: | |
statement.eval(env) | |
def __repr__(self): | |
return "(%s): self.condition = %s, self.true_block = %s, self.else_block = %s " %(self.__class__.__name__, self.condition, self.true_block, self.else_block) | |
def codegen(self): | |
commands = [] | |
# add if cond code | |
if_cond_commands = self.condition.codegen() | |
commands.extend(if_cond_commands) | |
commands.append("POP EAX") | |
# add dif jump comparisons --> if block | |
if isinstance(self.condition, GreaterThanOpTok): | |
commands.extend(["JG if_%s" % self.labelno]) #jump to ifblocklabel | |
elif isinstance(self.condition, LessThanOpTok): | |
commands.extend(["JL if_%s" % self.labelno]) | |
elif isinstance(self.condition, IsEqualToTok): | |
commands.extend (["JE if_%s" % self.labelno]) | |
#add elseif cond code | |
if self.elseif_block != None: | |
elseif_cond_commands = self.elseif_cond.codegen() | |
commands.extend(elseif_cond_commands) | |
commands.append("POP EAX") | |
#add dif jump comparisons --> else if block | |
if isinstance(self.elseif_cond, GreaterThanOpTok): | |
commands.extend(["JG %s" % self.elseif_label]) #jump to ifblocklabel | |
elif isinstance(self.elseif_cond, LessThanOpTok): | |
commands.extend(["JL %s" % self.elseif_label]) | |
elif isinstance(self.elseif_cond, IsEqualToTok): | |
commands.extend (["JE %s" % self.elseif_label]) | |
#else block commands | |
if self.else_block != None: | |
#jump to else | |
else_command = ["JMP %s" %self.else_label] | |
commands.extend(else_command) | |
#add true block code | |
true_block = ["if_%s:" % self.labelno] | |
for block in self.true_block: | |
true_block.extend(block.codegen()) | |
true_block.extend(["JMP endif_%s" %self.labelno]) | |
commands.extend(true_block) | |
#add else if true block | |
if self.elseif_block!=None: | |
else_if_block = ["%s:" %self.elseif_label] | |
for block in self.elseif_block: | |
else_if_block.extend(block.codegen()) | |
else_if_block.extend(["JMP endif_%s" %self.labelno]) | |
commands.extend(else_if_block) | |
#add else true block | |
if self.else_block!=None: | |
else_block = ["%s:" %self.else_label] | |
for block in self.else_block: | |
else_block.extend(block.codegen()) | |
else_block.extend(["JMP endif_%s" %self.labelno]) | |
commands.extend(else_block) | |
#end if | |
commands.extend(["endif_%s:" %self.labelno]) | |
return commands |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment