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