def condistmt(fabri=False): """Parses conditional statements.""" def brkunless(tokens): _, condexpr, _, body, _ = tokens return (condexpr and condexpr[1], body) def breakdown(tokens): _, _, condexpr, _, _, body, _, unlesses = tokens # Create list of flattened statements. stmtlist = [CondiJump([condexpr, len(body) + int(bool(unlesses))])] stmtlist.extend(body) if unlesses: # The offset created when due to the last UNLESS's lack of jumps. # The last UNLESS or a lone DEBATE will not jump off the end, # and if the last UNLESS has no clause, there will be no # conditional jump at the head of its body. jumpoffset = -2 + int(unlesses[-1][0] is not None) for idx, unless in enumerate(unlesses): # Check if this is a clauseless unless that isn't the last unless. if unless[0] is None and idx < len(unlesses) - 1: sys.stderr.write('SyntaxError: invalid unless format') sys.exit(SyntaxError) # Calculate jump length. bodylen = sum( map(lambda u: len(u[1]) + 2, unlesses[idx:]), jumpoffset ) # Add the jump that allows execution to jump to the end. stmtlist.append(CondiJump([None, bodylen])) # Add the jump at the head of this unless. if unless[0]: bodylen = len(unless[1]) + 3 + jumpoffset stmtlist.append(CondiJump([unless[0], bodylen])) # Add the body. stmtlist.extend(unless[1]) return stmtlist stmts = (stmtparser, funcstmts)[fabri] return ( kwdparser('DEBATE') + dlmparser('(') + exprparser() + dlmparser(')') + dlmparser('{') + LazierParser(stmts) + dlmparser('}') + OptionParser( RepeatParser( kwdparser('UNLESS') + OptionParser( dlmparser('(') + exprparser() + dlmparser(')') ) + dlmparser('{') + LazierParser(stmts) + dlmparser('}') ^ brkunless ) ) ^ breakdown )
def exprvalparser(): """Parses expression primitives.""" return (LazierParser(execexpr) | LazierParser(unaryexprparser) | idnparser | imgparser | fltparser | intparser | strparser)
def inspstmt(): def breakdown(tokens): kwd, _, args, _, _ = tokens return AthTokenStatement(kwd, args) return (kwdparser('INSPECT') + dlmparser('(') + LazierParser(callparser) + dlmparser(')') + dlmparser(';') ^ breakdown)
def exprgrpparser(): """Parses expression groups.""" return ( dlmparser('(') + LazierParser(exprparser) + dlmparser(')') ^ (lambda t: t[1]) )
def tildeath(): """Parses ~ATH loops.""" def breakdown(tokens): _, _, state, grave, _, _, body, _, coro = tokens body.pendant = grave.name return TildeAthLoop(bool(state), body, coro) return (kwdparser('~ATH') + dlmparser('(') + OptionParser(oprparser('!')) + idnparser + dlmparser(')') + dlmparser('{') + LazierParser(stmtparser) + dlmparser('}') + execfunc() ^ breakdown)
def fabristmt(): """Parses function declarations.""" def cull_seps(graft): return graft[0] or graft[1] def breakdown(tokens): kwd, name, _, args, _, _, body, _ = tokens body.pendant = name.name return AthTokenStatement( kwd, (AthCustomFunction(name.name, [arg.name for arg in args], body), )) return (kwdparser('FABRICATE') + varparser + dlmparser('(') + OptionParser( RepeatParser(varparser + OptionParser(dlmparser(',')) ^ cull_seps)) + dlmparser(')') + dlmparser('{') + LazierParser(funcstmts) + dlmparser('}') ^ breakdown)
def funcstmts(): """Parses the set of statements used in functions.""" return StmtParser(replistmt() # assignment # | propastmt() # reference | procrstmt() # val dec | bfctstmt() # obtain ptrs | aggrstmt() # stack ptrs | enumstmt() # split str | importstmt() # imports | inputstmt() # input | printfunc() # output | killfunc() # kill ctrl | execfunc() # run func | divlgstmt() # return | LazierParser(fabristmt) # func dec | tildeath() # cond loop | condistmt(True) # conditionals | inspstmt() # Debug, remove )