def p_arrow_one(self, param, op, body): assert ast.isloc(body) param = ast.map_value(val.symbol, param) return ast.locmerge(param, body, [ ast.map_value(val.symbol, ast.update_value(op, 'lambda')), ast.update_value(param, [param]), body, ])
def p_body_do(self, ss, semi, e): assert ast.isloc(ss) if e is None: e = ast.update_value(semi, val.symbol('pass')) assert ast.isloc(e) do = ast.locmerge(ss, e, val.symbol('do')) return ast.locmerge(ss, e, [do] + ss.value + [e])
def p_primary_proc(self, k, po, params, pc, bo, body, bc): assert ast.isloc(body) return ast.locmerge(k, bc, [ ast.map_value(val.symbol, ast.update_value(k, 'lambda')), ast.locmerge(po, pc, params), body, ])
def p_primary_if(self, k, po, p, pc, co, c, cc, ke, ao, a, ac): assert ast.isloc(p) assert ast.isloc(c) assert ast.isloc(a) return ast.locmerge( k, ac, [ast.map_value(val.symbol, ast.update_value(k, 'if')), p, c, a])
def p_arrow_tuple(self, po, params, pc, op, body): assert ast.isloc(body) return ast.locmerge(po, body, [ ast.map_value(val.symbol, ast.update_value(op, 'lambda')), ast.locmerge(po, pc, params), body, ])
def p_primary_paren(self, o, es, c): assert isinstance(es, list) and all(map(ast.isloc, es)) if len(es) == 1: [e] = es return ast.locmerge(o, c, e.value) else: keyword = ast.update_value(o, val.symbol('values_list')) construction = [keyword] + es return ast.locmerge(o, c, construction)
def _p_binop(self, l, op, r): assert ast.isloc(l) assert ast.isloc(r) if op.value in operators: # Perform operator substitution new_op = ast.update_value(op, operators[op.value]) else: # Leave it new_op = op app = [ast.map_value(val.symbol, new_op), l, r] return ast.locmerge(l, r, app)
def p_directive_assume(self, k, n, e): # Fun fact. This manipulation (and the similar treatment of # observe and predict, here and in the VentureScript parser) # breaks an invariant that parsing used to satisfy. To wit, # once upon a time it was the case that the string picked out # by the location tags of every node in a parse tree was # guaranteed to re-parse to an equal node. This cannot be the # case now, because the 'expr' node constructed here is not # parsed from the string, but synthesized based on knowing # that its constituents appear in an 'assume' directive. expr = [ ast.update_value(k, val.symbol('assume')), ast.map_value(val.symbol, n), e ] return expression_evaluation_instruction(ast.loclist(expr))
def p_applicative_lookup(self, a, o, index, c): assert ast.isloc(a) assert ast.isloc(index) lookup = ast.update_value(o, val.sym('lookup')) return ast.locmerge(a, c, [lookup, a, index])
def p_hash_tag_tag_val(self, e, h, tag, colon, value): tag_proc = ast.update_value(h, val.symbol('tag')) name = locquoted(h, tag, val.quasiquote) app = [tag_proc, name, value, e] return ast.locmerge(e, value, app)
def p_unary_neg(self, op, e): return self._p_binop(ast.update_value(op, val.number(0)), op, e)
def p_statement_letvalues(self, l, po, names, pc, eq, e): assert ast.isloc(e) assert all(map(ast.isloc, names)) let = ast.update_value(l, val.symbol('let_values')) names = ast.locmerge(po, pc, names) return ast.locmerge(let, e, [let, names, e])
def p_hash_tag_tag(self, e, h, tag): tag_proc = ast.update_value(h, val.symbol('tag')) name = locquoted(h, tag, val.quasiquote) value = ast.update_value(h, val.string("default")) app = [tag_proc, name, value, e] return ast.locmerge(e, tag_proc, app)
def p_directive_infer(self, k, e): assert ast.isloc(e) i = ast.update_value(k, val.symbol('do')) app = [i, e] return ast.locmerge(i, e, app)
def p_literal_true(self, t): return ast.map_value(val.boolean, ast.update_value(t, True))
def p_directive_observe(self, k, e, eq, e1): assert ast.isloc(e) assert ast.isloc(e1) i = ast.update_value(k, val.symbol('observe')) app = [i, e, e1] return ast.locmerge(i, e1, app)
def p_path_expression_one(self, slash, s): assert ast.isloc(s) top = ast.update_value(slash, val.symbol('by_top')) intersect = ast.update_value(slash, val.symbol('by_walk')) app = [intersect, ast.loclist([top]), s] return ast.locmerge(top, s, app)
def p_action_sample(self, k, e): assert ast.isloc(e) i = ast.update_value(k, val.symbol('sample')) app = [i, e] return ast.locmerge(i, e, app)
def p_statements_one(self, s): assert ast.isloc(s) return ast.update_value(s, [s])
def p_action_force(self, k, e1, eq, e2): assert ast.isloc(e1) assert ast.isloc(e2) i = ast.update_value(k, val.symbol('force')) app = [i, e1, e2] return ast.locmerge(i, e2, app)
def p_do_bind_labelled(self, n, op, l): assert ast.isloc(l) # XXX Yes, this remains infix, for the macro expander to handle... # XXX Convert <~ to <- for the macro expander's sake expression = [n, ast.update_value(op, val.symbol("<-")), l] return ast.locmerge(n, l, expression)
def p_statement_assign(self, n, eq, e): assert ast.isloc(e) let = ast.update_value(eq, val.symbol('let')) n = ast.map_value(val.symbol, n) return ast.locmerge(n, e, [let, n, e])
def p_command_load(self, k, pathname): i = ast.update_value(k, 'load') return ast.locmerge(i, pathname, {'instruction': i, 'file': pathname})
def p_path_expression_some(self, more, slash, s): # XXX Is this just _p_binop with the "slash" operator? assert ast.isloc(s) intersect = ast.update_value(slash, val.symbol('by_walk')) app = [intersect, more, s] return ast.locmerge(more, s, app)
def p_command_define(self, k, n, eq, e): assert ast.isloc(e) i = ast.update_value(k, 'define') s = ast.map_value(val.symbol, n) instruction = {'instruction': i, 'symbol': s, 'expression': e} return ast.locmerge(i, e, instruction)
def p_path_step_tag_val(self, q, tag, eq, value): by_tag_value = ast.update_value(q, val.symbol('by_tag_value')) name = locquoted(q, tag, val.quasiquote) app = [by_tag_value, name, value] return ast.locmerge(by_tag_value, value, app)
def p_primary_array(self, o, a, c): assert isinstance(a, list) construction = [ast.update_value(o, val.symbol('array'))] + a return ast.locmerge(o, c, construction)
def p_path_step_star(self, star): return ast.update_value(star, [val.symbol('by_star')])
def p_literal_false(self, f): return ast.map_value(val.boolean, ast.update_value(f, False))
def p_statement_mutrec(self, l, n, eq, e): assert ast.isloc(e) let = ast.update_value(l, val.symbol('mutrec')) n = ast.map_value(val.symbol, n) return ast.locmerge(let, e, [let, n, e])