def p_accesschain(p): """accesschain : WORD | accesschain OP_DOT WORD""" if len(p) > 2: p[0] = syntax.EGetField(p[1], p[3]) else: p[0] = syntax.EVar(p[1])
def p_basicstm(p): """basicstm : accesschain OP_OPEN_PAREN exp_list OP_CLOSE_PAREN OP_SEMICOLON | accesschain OP_ASSIGN exp OP_SEMICOLON | KW_IF exp block maybeelse | KW_LET WORD OP_ASSIGN exp OP_SEMICOLON""" if p[1] == "if": p[0] = syntax.SIf(p[2], p[3], p[4]) elif p[1] == "let": p[0] = syntax.SDecl(syntax.EVar(p[2]), p[4]) elif p[2] == "(": if not isinstance(p[1], syntax.EGetField): report_parse_error( p[1], "Method calls must have the form `target.method(...)`") p[0] = syntax.SCall(p[1].e, p[1].field_name, p[3]) else: p[0] = syntax.SAssign(p[1], p[3])
def delta_form(members: [(str, syntax.Type)], op: syntax.Op) -> { str: syntax.Exp }: """ Given the abstract state of a data structure and an imperative operation that modifies it, return new values for the abstract state in terms of the old values. Input: members - a list of (id, type) tuples specifying the abstract state op - an imperative operation Output: dictionary mapping id->new_exp (suitable for use by syntax_tools.subst) """ res = {v: syntax.EVar(v).with_type(t) for (v, t) in members} return _delta_form(res, op.body)
def p_exp(p): """exp : NUM | FLOAT | WORD | WORD OP_OPEN_PAREN exp_list OP_CLOSE_PAREN | KW_TRUE | KW_FALSE | exp OP_PLUS exp | exp OP_MINUS exp | exp OP_TIMES exp | exp OP_EQ exp | exp OP_NE exp | exp OP_LT exp | exp OP_LE exp | exp OP_GT exp | exp OP_GE exp | exp KW_AND exp | exp KW_OR exp | exp OP_IMPLIES exp | exp OP_QUESTION exp OP_COLON exp | exp OP_OPEN_BRACKET slice OP_CLOSE_BRACKET | KW_NOT exp | OP_MINUS exp | exp KW_IN exp | KW_UNIQUE exp | KW_DISTINCT exp | KW_EMPTY exp | KW_THE exp | KW_MIN exp | KW_MAX exp | KW_ARGMIN lambda exp | KW_ARGMAX lambda exp | KW_SUM exp | KW_LEN exp | KW_ANY exp | KW_ALL exp | KW_EXISTS exp | KW_REVERSED exp | exp OP_DOT NUM | exp OP_DOT WORD | OP_OPEN_PAREN exp_list OP_CLOSE_PAREN | OP_OPEN_BRACE record_fields OP_CLOSE_BRACE | OP_OPEN_BRACKET exp OP_CLOSE_BRACKET | OP_OPEN_BRACKET exp OP_VBAR comprehension_body OP_CLOSE_BRACKET""" if len(p) == 2: if type(p[1]) is syntax.ENum: p[0] = p[1] elif p[1] == "true": p[0] = syntax.EBool(True) elif p[1] == "false": p[0] = syntax.EBool(False) else: p[0] = syntax.EVar(p[1]) elif len(p) == 3: if p[1] == "min": p[0] = syntax.EArgMin( p[2], syntax.ELambda(syntax.EVar("x"), syntax.EVar("x"))) elif p[1] == "max": p[0] = syntax.EArgMax( p[2], syntax.ELambda(syntax.EVar("x"), syntax.EVar("x"))) else: p[0] = syntax.EUnaryOp(p[1], p[2]) elif len(p) == 4: if p[1] == "(": exps = p[2] if len(exps) == 0: raise Exception("illegal ()") elif len(exps) == 1: p[0] = exps[0] elif len(exps) > 1: p[0] = syntax.ETuple(tuple(exps)) elif p[1] == "[": p[0] = syntax.ESingleton(p[2]) elif p[1] == "{": p[0] = syntax.EMakeRecord(p[2]) elif p[2] == ".": if isinstance(p[3], syntax.ENum): p[0] = syntax.ETupleGet(p[1], p[3].val) else: p[0] = syntax.EGetField(p[1], p[3]) elif p[1] == "argmin": p[0] = syntax.EArgMin(p[3], p[2]) elif p[1] == "argmax": p[0] = syntax.EArgMax(p[3], p[2]) else: p[0] = syntax.EBinOp(p[1], p[2], p[3]) else: if p[2] == "?": p[0] = syntax.ECond(p[1], p[3], p[5]) elif p[2] == "[": if isinstance(p[3], syntax.Exp): p[0] = syntax.EListGet(p[1], p[3]) elif isinstance(p[3], tuple): start = p[3][0] end = p[3][1] if start is None: start = syntax.ZERO if end is None: end = syntax.ELen(p[1]) p[0] = syntax.EListSlice(p[1], start, end) elif p[1] == "[": p[0] = syntax.EListComprehension(p[2], p[4]) elif p[2] == "(": p[0] = syntax.ECall(p[1], p[3]) else: assert False, "unknown case: {}".format(repr(p[1:]))
def p_lambda(p): """lambda : OP_OPEN_BRACE WORD OP_RIGHT_ARROW exp OP_CLOSE_BRACE""" p[0] = syntax.ELambda(syntax.EVar(p[2]), p[4])