language

some fools attempt at an interpreted language
Log | Files | Refs | README

interpreter.py (7634B)


      1 from parser import *
      2 from lexer import *
      3 from bytecode import *
      4 from memonic import *
      5 from helper import *
      6 from namespace import *
      7 
      8 class AbstractToken():
      9 	def __init__(self, interpreter_instance, raw_data):
     10 		self.data = raw_data
     11 		self.expr = []
     12 		self.i    = interpreter_instance
     13 		self.line = self.i.line
     14 		self.update()
     15 	
     16 	def update(self):
     17 		pass
     18 	
     19 	def action(self):
     20 		pass
     21 
     22 class Label(AbstractToken):
     23 	def update(self):
     24 		f = lambda y, x: y(y, x[0]) if type(x) is list else x
     25 		self.data = f(f, self.data)
     26 
     27 		self.is_property = False
     28 		self.parent      = None
     29 		self.name        = None
     30 
     31 		names = self.data.rsplit(".", 1)
     32 
     33 		# Determine if we're a simple property or a property that is part of an
     34 		# object, or if it exists at the root level of a namespace
     35 		if len(names) > 1:
     36 			self.is_property = True
     37 			self.parent = Label(self.i, names[0])
     38 			self.parent.update()
     39 
     40 			self.name = names[1]
     41 
     42 			t = self.i.ns.resolve_with_obj(self.parent, self.name)
     43 			if t == None:
     44 				fatal_error(self.i, "Cannot resolve name " + self.data)
     45 			else:
     46 				self.expr = t[0]
     47 
     48 		else:
     49 			self.name = names[0]
     50 
     51 			if self.name == "ref":
     52 				self.scope = 1
     53 				self.expr = 0
     54 			else:
     55 				t = self.i.ns.resolve(self.name)
     56 
     57 				if t == None:
     58 					fatal_error(self.i, "Cannot resolve name " + self.name)
     59 				else:
     60 					self.scope = t[0]
     61 					self.expr = t[1]
     62 
     63 	def action(self, s=False):
     64 		if s:
     65 			return(self.scope)
     66 		else:
     67 			return(int_to_word(self.expr))
     68 
     69 class Arguements(AbstractToken):
     70 	def update(self):
     71 		if len(self.data) > 0:
     72 			if self.data[0] == "(":
     73 				t = self.data[1:]
     74 			else:
     75 				t = self.data
     76 		else:
     77 			t = self.data
     78 
     79 		tokens = token_split(t,
     80 		                     [["[", "("], ["]", ")"]],
     81 		                     [","], include_splitter = False)
     82 
     83 		for t in tokens:
     84 			self.expr.insert(0, Expression(self.i, t))
     85 
     86 	def action(self):
     87 		rv = []
     88 		for i in self.expr:
     89 			rv.append([i.action(), OP_ARGB])
     90 		return rv
     91 
     92 class Type(AbstractToken):
     93 	type_string = ""
     94 	is_object = False
     95 	def update(self):
     96 		n = None
     97 		for x, t in enumerate(self.i.p.defined_types):
     98 			r = t.match(self.data, 0)
     99 			if r[0]:
    100 				self.type_string = self.data
    101 				n = x
    102 
    103 		if n == None:
    104 			self.is_object = True
    105 			self.type_string = self.data[0]
    106 			n = self.i.p.TYPE_OBJECT
    107 
    108 		self.expr = n
    109 
    110 	def action(self):
    111 		return(self.expr)
    112 
    113 class Parameters(AbstractToken):
    114 	def update(self):
    115 		tmp = []
    116 		for x in self.data:
    117 			if x != ",":
    118 				tmp.append(x)
    119 			elif x == ",":
    120 				self.i.new_name_token(tmp[1:])
    121 				t = Type(self.i, tmp[:-1])
    122 				l = Label(self.i, tmp[1:])
    123 				self.expr.append([t, l])
    124 				tmp = []
    125 
    126 		if len(tmp) > 0:
    127 			self.i.new_name_token(tmp[1:])
    128 			t = Type(self.i, tmp[:-1])
    129 			l = Label(self.i, tmp[1:])
    130 			self.expr.append([t, l])
    131 
    132 		for x in self.expr:
    133 			if x[0].is_object:
    134 				self.i.ns.copy(x[1].name, x[0].type_string)
    135 
    136 	def action(self):
    137 		types = list(map(lambda x: x[0].action(), self.expr))
    138 		return([
    139 		        int_to_bytes(len(types)),
    140 		        0x0,
    141 		        types
    142 		       ])
    143 
    144 
    145 class Expression(AbstractToken):
    146 	def update(self):
    147 		self.expr = None
    148 		self.operators = [
    149 			["+", Opcode(OP_ADD)],
    150 			["-", Opcode(OP_SUB)],
    151 			["*", Opcode(OP_MULT)],
    152 			["/", Opcode(OP_DIV)],
    153 			["%", Opcode(OP_MOD)],
    154 			["==", Opcode(OP_EQ)],
    155 			["!=", Opcode(OP_NEQ)],
    156 			[">", Opcode(OP_GTHAN)],
    157 			["<", Opcode(OP_LTHAN)],
    158 			[">=", Opcode(OP_GTHAN_EQ)],
    159 			["=<", Opcode(OP_LTHAN_EQ)]
    160 		]
    161 		# Flatten the above array
    162 		self.operator_names = list(map(lambda x: x[0], self.operators))
    163 
    164 		self.func_call = Statement(
    165 			"func_call",
    166 			expression=[
    167 				self.i.p.label_def,
    168 				self.i.p.paramlist_def
    169 			],
    170 			init=(lambda x,y: FunctionCall(Label(x,y[0]),
    171 			                               Arguements(x,y[1:])))
    172 		)
    173 
    174 		self.subexpr = Statement(
    175 			"subexpr",
    176 			expression=[
    177 				self.i.p.paramlist_def
    178 			],
    179 			init=(lambda x,y: Expression(x, y[1:-1]))
    180 		)
    181 		self.integer = Statement(
    182 			"integer",
    183 			expression=[
    184 				self.i.p.int_def
    185 			],
    186 			init=(lambda x,y: IntegerConstant(y))
    187 		)
    188 		self.label = Statement(
    189 			"label",
    190 			expression=[
    191 				self.i.p.label_def
    192 			],
    193 			init=(lambda x,y: VariableGet(Label(x, y)))
    194 		)
    195 
    196 		self.identifiers = [
    197 			self.func_call,
    198 			self.subexpr,
    199 			self.integer,
    200 			self.label
    201 		]
    202 
    203 		self.group_char = [["[", "("], ["]", ")"]]
    204 		t = token_split(self.data,
    205 		                self.group_char,
    206 		                self.operator_names)
    207 
    208 		if len(t) == 0:
    209 			t = self.data
    210 		if len(t) > 2:
    211 			fatal_error(self.i, "Expression Error ({})".format(self.data))
    212 
    213 		next_op = False
    214 		for thing in t:
    215 			if thing[-1] in self.operator_names:
    216 				ex = thing[:-1]
    217 				op = thing[-1]
    218 			else:
    219 				ex = thing
    220 				op = None
    221 
    222 			obj = None
    223 			if ex[0][0] == "\0":
    224 				obj = StringConstant(ex[0][2:-1])
    225 			else:
    226 				for i in self.identifiers:
    227 					r = i.match(ex)
    228 					if r:
    229 						obj = i.action(self.i, ex)
    230 
    231 			if obj == None:
    232 				fatal_error(self.i, "Unknown Expression Error ({})".format(ex))
    233 				break
    234 
    235 			if next_op:
    236 				self.expr.vals.append(obj)
    237 				next_op = False
    238 			else:
    239 				if op in self.operator_names:
    240 					index = self.operator_names.index(op)
    241 					self.expr = BinaryOp(obj, self.operators[index][1])
    242 					next_op = True
    243 				else:
    244 					self.expr = obj
    245 
    246 	def action(self):
    247 		return(self.expr.action());
    248 
    249 class Directive():
    250 	def __init__(self, function, conditional):
    251 		self.action = function
    252 		self.cond = conditional
    253 
    254 class Interpreter():
    255 	def __init__(self, filename):
    256 		self.p = Parser(filename)
    257 		self.ns = Namespace()
    258 
    259 		self.success = False
    260 		self.program = self.p.get_statements()
    261 
    262 		if self.program == False:
    263 			print("Terminating parsing...")
    264 		else:
    265 			self.line = (None, None)
    266 
    267 			self.ln   = 0
    268 
    269 			self.cur_directives = []
    270 
    271 			self.directives = [self.cur_directives]
    272 
    273 			self.success = True
    274 			for self.ln, self.line in enumerate(self.program):
    275 				t = self.line[0].action(self)
    276 				for i in t:
    277 					if i != False:
    278 						self.line[2].append(i)
    279 
    280 	def nxt(self, n):
    281 		if len(self.program) <= self.ln + n:
    282 			return self.program[self.ln]
    283 		return self.program[self.ln + n]
    284 
    285 	def ns_persist(self, index):
    286 		self.ns.target(self.line[1][index][0])
    287 		return False
    288 	
    289 	def ns_save(self):
    290 		self.ns.release()
    291 		return False
    292 	
    293 	def ns_copy(self, key, index):
    294 		self.ns.copy(self.line[1][key][0], self.line[1][index][0])
    295 		return False
    296 
    297 	def new_name(self, index):
    298 		self.new_name_token(self.line[1][index])
    299 		return False
    300 
    301 	def new_name_token(self, token):
    302 		f = lambda y, x: y(y, x[0]) if type(x) is list else x
    303 
    304 		self.ns.name_dec(f(f, token))
    305 
    306 	def push_scope(self):
    307 		self.ns.push()
    308 		return False
    309 	
    310 	def pop_scope(self):
    311 		self.ns.pop()
    312 		return False
    313 
    314 	def inc_scope(self):
    315 		self.ns.inc_scope()
    316 		return False
    317 
    318 	def dec_scope(self):
    319 		self.ns.dec_scope()
    320 		return False
    321 
    322 	def push_directives(self):
    323 		self.directives.append(self.cur_directives)
    324 		self.cur_directives = []
    325 		return False
    326 
    327 	def pop_directives(self):
    328 		t = self.directives.pop()
    329 		for x in t:
    330 			if x.cond(self):
    331 				self.cur_directives.append(x)
    332 			else:
    333 				r = x.action(self)
    334 				for i in r:
    335 					if i != False:
    336 						self.line[2].append(i)
    337 
    338 		return False
    339 
    340 	def add_directive(self, directive, cond=(lambda x: False)):
    341 		d = Directive(directive, cond)
    342 		self.cur_directives.append(d)
    343 		return False
    344 
    345 	def op(self, opcode):
    346 		return(Opcode(opcode))
    347 
    348 	def eval_label(self, index):
    349 		return(Label(self, self.line[1][index]))
    350 
    351 	def eval_args(self, index):
    352 		return(Arguements(self, self.line[1][index]))
    353 
    354 	def eval_type(self, index):
    355 		return(Type(self, self.line[1][index]))
    356 
    357 	def eval_param(self, index):
    358 		return(Parameters(self, self.line[1][index]))
    359 
    360 	def eval_expr(self, index):
    361 		return(Expression(self, self.line[1][index]))
    362