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_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_instruction_labelled(self, l, open, d, close): label = ast.map_value(val.symbol, l) if d['instruction'].value == 'evaluate': # The grammar only permits expressions that are calls to # the 'assume', 'observe', or 'predict' macros to be # labeled with syntactic sugar. locexp = d['expression'] exp = locexp.value new_exp = exp + [label] new_locexp = ast.Located(locexp.loc, new_exp) new_d = expression_evaluation_instruction(new_locexp) return ast.locmerge(l, close, new_d) else: d['label'] = label d['instruction'] = ast.map_value(lambda i: 'labeled_' + i, d['instruction']) return ast.locmerge(l, close, d)
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_literal_true(self, t): return ast.map_value(val.boolean, ast.update_value(t, True))
def p_params_many(self, params, c, param): params.append(ast.map_value(val.symbol, param)) return params
def p_params_one(self, param): return [ast.map_value(val.symbol, param)]
def p_primary_symbol(self, s): return ast.map_value(val.symbol, s)
def p_labelled_directive(self, l, d): label = ast.map_value(val.symbol, l) exp = d.value new_exp = exp + [label] new_d = ast.locmerge(label, d, new_exp) return new_d
def p_literal_real(self, v): return ast.map_value(val.number, v)
def p_directive_define(self, k, n, e): return { 'instruction': ast.update_value(k, 'define'), 'symbol': ast.map_value(val.symbol, n), 'expression': e }
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])
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_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_directive_assume(self, k, n, eq, e): assert ast.isloc(e) i = ast.update_value(k, val.symbol('assume')) s = ast.map_value(val.symbol, n) app = [i, s, e] return ast.locmerge(i, e, app)
def p_literal_false(self, f): return ast.map_value(val.boolean, ast.update_value(f, False))
def p_expression_operator(self, op): assert op.value in operators return ast.map_value(lambda op: val.symbol(operators[op]), op)
def p_literal_integer(self, v): return ast.map_value(val.number, v)
def p_expression_symbol(self, name): return ast.map_value(val.symbol, name)
def p_literal_string(self, v): return ast.map_value(val.string, v)
def p_names_some(self, ns, n): ns.append(ast.map_value(val.symbol, n)) return ns