def expandMacro(ppt, name, arglist): global macros if name not in macros: Err.log("Undefined macro '%s'" % name) return IR.NullNode argexprs = [ IR.Node(ppt, "Label", "_*%d" % i, arg) for (i, arg) in zip(xrange(1, sys.maxint), arglist) ] bindexprs = [ IR.Node(ppt, "Label", "_%d" % i, IR.LabelExpr("_*%d" % i)) for i in range(1, len(arglist) + 1) ] body = [ IR.Node("%s->%s" % (ppt, node.ppt), node.nodetype, *node.data) for node in macros[name] ] invocation = [IR.Node(ppt, "ScopeBegin")] + argexprs + [ IR.Node(ppt, "ScopeBegin") ] + bindexprs + body + [ IR.Node(ppt, "ScopeEnd"), IR.Node(ppt, "ScopeEnd") ] return IR.SequenceNode(ppt, invocation)
def parse(filenames): """Top level parsing routine, taking a source file name list and returning an IR list.""" global templabelcount templabelcount = 0 nodes = [parse_file("<Top Level>", f) for f in filenames] if len(nodes) == 1: return nodes[0] return IR.SequenceNode("<Top level>", nodes)
def parse_file(ppt, filename): "Loads a .P65 source file, and returns an IR list." Err.currentpoint = ppt if Cmd.verbose > 0: print("Loading " + filename) try: f = open(filename, 'r', encoding='utf-8') linelist = f.readlines() f.close() pptlist = ["%s:%d" % (filename, i + 1) for i in range(len(linelist))] lexlist = map(lex, pptlist, linelist) IRlist = map(parse_line, pptlist, lexlist) IRlist = [node for node in IRlist if node is not IR.NullNode] return IR.SequenceNode(ppt, IRlist) except IOError: Err.log("Could not read " + filename) return IR.NullNode
def parse_file(ppt, filename, load_once=False): "Loads an Ophis source file, and returns an IR list." global context_directory, loadedfiles Err.currentpoint = ppt old_context = context_directory if filename != '-': if context_directory is not None: filename = os.path.abspath( os.path.join(context_directory, filename)) if load_once and filename in loadedfiles: if Cmd.print_loaded_files: print("Skipping " + filename, file=sys.stderr) return IR.NullNode loadedfiles[filename] = True if Cmd.print_loaded_files: if filename != '-': print("Loading " + filename, file=sys.stderr) else: print("Loading from standard input", file=sys.stderr) try: if filename != '-': if context_directory is not None: filename = os.path.join(context_directory, filename) f = open(filename, "rt") linelist = f.readlines() f.close() context_directory = os.path.abspath(os.path.dirname(filename)) else: context_directory = os.getcwd() linelist = sys.stdin.readlines() pptlist = ["%s:%d" % (filename, i + 1) for i in range(len(linelist))] lexlist = list(map(lex, pptlist, linelist)) IRlist = list(map(parse_line, pptlist, lexlist)) IRlist = [node for node in IRlist if node is not IR.NullNode] context_directory = old_context return IR.SequenceNode(ppt, IRlist) except IOError: Err.log("Could not read " + filename) context_directory = old_context return IR.NullNode
def parse_line(ppt, lexemelist): "Turn a line of source into an IR Node." Err.currentpoint = ppt result = [] line = ParseLine(lexemelist) def aux(): "Accumulates all IR nodes defined by this line." if line.lookahead(0).type == "EOL": pass elif line.lookahead(1).type == ":": newlabel = line.expect("LABEL").value line.expect(":") result.append(IR.Node(ppt, "Label", newlabel, IR.PCExpr())) aux() elif line.lookahead(0).type == "*": global templabelcount templabelcount = templabelcount + 1 result.append( IR.Node(ppt, "Label", "*" + str(templabelcount), IR.PCExpr())) line.expect("*") aux() elif line.lookahead(0).type == "." or line.lookahead(0).type == "`": which = line.expect(".", "`").type if (which == "."): pragma = line.expect("LABEL").value else: pragma = "invoke" pragmaFunction = "pragma" + pragma.title() for mod in pragma_modules: if hasattr(mod, pragmaFunction): getattr(mod, pragmaFunction)(ppt, line, result) break else: Err.log("Unknown pragma " + pragma) else: # Instruction opcode = line.expect("OPCODE").value arg2 = None if line.lookahead(0).type == "#": mode = "Immediate" line.expect("#") arg = parse_expr(line) line.expect("EOL") elif line.lookahead(0).type == "(": line.expect("(") arg = parse_expr(line) if line.lookahead(0).type == ",": line.expect(",") if line.lookahead(0).type == "X": mode = "PointerX" line.expect("X") line.expect(")") line.expect("EOL") else: mode = "PointerSPY" line.expect("SP") line.expect(")") line.expect(",") line.expect("Y") line.expect("EOL") else: line.expect(")") tok = line.expect(",", "EOL").type if tok == "EOL": mode = "Pointer" else: if line.lookahead(0).type == "Y": mode = "PointerY" line.expect("Y") line.expect("EOL") else: mode = "PointerZ" line.expect("Z") line.expect("EOL") elif line.lookahead(0).type == "EOL": mode = "Implied" arg = None else: arg = parse_expr(line) tok = line.expect("EOL", ",").type if tok == ",": # Parser has to special-case the BBXn instructions, # Which uniquely take two addresses if opcode[:3] in ["bbs", "bbr"]: arg2 = parse_expr(line) mode = "Memory2" else: tok = line.expect("X", "Y", "Z").type if tok == "X": mode = "MemoryX" elif tok == "Y": mode = "MemoryY" else: mode = "MemoryZ" line.expect("EOL") else: mode = "Memory" result.append(IR.Node(ppt, mode, opcode, arg, arg2)) aux() result = [node for node in result if node is not IR.NullNode] if len(result) == 0: return IR.NullNode if len(result) == 1: return result[0] return IR.SequenceNode(ppt, result)