def run(self, env): for i in range(len(self.args[1::2])): # Initialize all our variables env.vars[self.args[1::2][i]] = (self.args[i * 2], '0') env.funcs[self.name] = self.args # Put our function in the dictionary env.write('jmp e%s' % self.name) # Jump over our function until it is called env.write('%s:' % self.name) # Add our label env.indent += 1 env.pos += 1 level = 1 # The bracket level while level != 0: if parser.end(env.lines[env.pos] ): # A statement ended, decrement the bracket level level -= 1 else: start = '{' in env.lines[ env.pos] # Check if a statement started stream = lexer.lex(env.lines[env.pos]) # Lex the current line func, stream = parser.parse(stream) # Parse it stream = [token[0] for token in stream] # Remove the tags func = mapping[func](stream) func.run(env) # Run the function, this adds stuff to the file if '{' in env.lines[ env.pos]: # A statement began, increment the bracket level level += 1 if level == 0: env.pos += 1 break env.write('ret') # Return env.indent -= 1 env.write('e%s:' % self.name) # Label used to jump over our function env.indent += 1 env.write('nop') # Do nothing env.indent -= 1
def run(self, env): env.pos += 1 for i in range(env.pos, len(env.lines)): if parser.end(env.lines[i]): # The statement ended env.pos = i + 1 return else: if '}' not in env.lines[ i]: # Write the current line directly to the file env.write(env.lines[i].strip())
def run(self, env): if self.a in env.vars: # A is a variable, get its value self.a = '%s [%s]' % (env.vars[self.a][0], self.a) if self.b in env.vars: # B is a variable, get its value self.b = env.vars[self.b] self.name = 'i%d:' % env.ifs # Get the name for our label env.ifs += 1 # Increment the number of labels env.write('cmp %s, %s' % (self.a, self.b)) # Compare our two values env.write(jmps[self.op] + ' ' + self.name.rstrip(':') ) # If they match the operator, jump to our label env.write('jmp ' + self.name.rstrip(':') + 'e') # Jump over our label env.write(self.name) # Create our label env.indent += 1 # Indent env.pos += 1 level = 1 # The bracket level while level != 0: if parser.end( env.lines[env.pos] ): # We just ended a statement, so decrement the bracket level level -= 1 else: stream = lexer.lex(env.lines[env.pos]) # Lex the current line func, stream = parser.parse(stream) # Parse it stream = [token[0] for token in stream] # Remove the tag func = mapping[func](stream) func.run( env) # Run it, this causes stuff to be written to the file env.pos -= 1 if '{' in env.lines[ env. pos]: # We began a statement, so increment the bracket level level += 1 if level == 0: env.pos += 1 break env.indent -= 1 env.write(self.name.rstrip(':') + 'e:') # The label used to jump over our label env.indent += 1 env.write('nop') # Our label should not do anything env.indent -= 1
def run(self, file): ''' The run method. Iterate over every line in the file, lex, parse, and run it. ''' code = pre.pre(file.read()) # Preprocess the input code lines = code.split('\n') # Split the code into lines self.lines = lines # Store the lines so functions can access them while '' in lines: lines.remove('') # Remove empty lines while self.pos < len(lines): line = lines[self.pos] # Get the current line stream = lexer.lex(line) # Lex the line if parser.end( line ): # The line is a } (used for ending statements), so we should skip it self.pos += 1 continue elif stream: func, stream = parser.parse(stream) # Parse the lexed stream stream = [ token[0] for token in stream ] # We don't need the tag part of the stream, only the text func = mapping[func](stream) func.run(self) # Run the function we got else: self.pos += 1 self.write( 'ret' ) # Return from main function, needed to avoid segmenation fault self.indent = 1 self.write('section .data', False) # The data section, store variables here for var in self.vars: type = 'd' + self.vars[var][0][ 0] # Define a variable of the right type if self.vars[var][1][0] == '"': self.write('%s: %s %s' % (var, type, self.vars[var][1])) else: self.write('%s: %s 0' % (var, type))
def run(self, env): self.var = '%s [%s]' % ( env.vars[self.var][0], self.var ) # Make sure we take the value, not the address, of our variable self.name = 'f%d:' % env.loops # The name of our loop env.loops += 1 env.write('mov %s, %s' % (self.var, self.min)) # Set the variable to our minimum env.write(self.name) # Add our label env.indent += 1 env.pos += 1 level = 1 # The bracket level while level != 0: # While the statement is still going if parser.end(env.lines[env.pos] ): # A statement ended, decrement the bracket level level -= 1 else: start = '{' in env.lines[ env.pos] # Check whether a statement has started stream = lexer.lex(env.lines[env.pos]) # Lex the current line func, stream = parser.parse(stream) # Parse it stream = [token[0] for token in stream] # Remove the tags func = mapping[func](stream) func.run(env) # Run the function, this adds stuff to the file if start: env.pos -= 1 if '{' in env.lines[ env.pos]: # A statement ended, increment the bracket level level += 1 if level == 0: env.pos += 1 break env.write('inc %s' % self.var) # Increment our variable env.write('cmp %s, %s' % (self.var, self.max)) # Compare it to the max env.write('jl ' + self.name.rstrip(':') ) # If it is less than it, jump back to our loop env.indent -= 1
def run(self, env): if self.b in env.vars: self.b = env.vars[self.b][1] # B is a variable, get its value eval = 0 self.name = 'w%d:' % env.loops # The name of our loop env.loops += 1 # Increment the number of loops env.write(self.name) # Add our label env.indent += 1 env.pos += 1 level = 1 # The bracket level while level != 0: # While the statement is not over if parser.end( env.lines[env.pos] ): # A statement ended, so decrement the bracket level level -= 1 else: stream = lexer.lex(env.lines[env.pos]) # Lex the current line func, stream = parser.parse(stream) # Parse it stream = [token[0] for token in stream] # Remove the tags func = mapping[func](stream) func.run(env) # Run it, this adds stuff to the file env.pos -= 1 if '{' in env.lines[ env. pos]: # A statement began, so increment the bracket level level += 1 if level == 0: env.pos += 1 break if self.a2 in env.vars: # A is a variable, so take its value self.a2 = '%s [%s]' % (env.vars[self.a2][0], self.a2) env.write('cmp %s, %s' % (self.a2, self.b)) # Compare the a and b values env.write(jmps[self.op] + ' ' + self.name.rstrip(':')) # Jump to our loop env.indent -= 1