Ejemplo n.º 1
0
def p_UnaryExpr(p):
    """UnaryExpr : PrimaryExpr
                 | unary_op UnaryExpr
    """
    if len(p) == 2:  # PrimaryExpr
        p[0] = p[1]
    else:  # unary_op used
        if isinstance(p[2], GoBasicLit):  # Direct calculation
            error = False
            try:
                if p[2].dtype.name in ("string", "rune"):  # Error
                    error = True
                elif p[1][0] == "+":
                    pass
                elif p[1][0] == "-":
                    p[2].item = -1 * p[2].item
                elif p[1][0] == "!":
                    p[2].item = not p[2].item
                elif p[1][0] == "^":
                    if p[2].dtype.name == "int":
                        p[2].item = ~p[2].item
                    else:
                        error = True
                elif p[1][0] == "*":
                    error = True
                elif p[1][0] == "++":
                    # p[2].item += 1
                    error = True
                elif p[1][0] == "--":
                    # p[2].item -= 1
                    error = True
                else:
                    error = True
            except Exception:
                error = True

            if error:
                position = go_traceback(p.slice[1].value)
                print(
                    'SyntaxError: Unary operator "{}" not applicable for '
                    'argument of type "{}" at position {}'.format(
                        p[1][0], p[2].dtype.name.lower(), position
                    )
                )
                exit(1)
            else:
                p[0] = p[2]
        else:
            # 1st arg. is expression, 2nd arg. is unary_op
            if p[1][0] in ["++", "--"]:
                position = go_traceback(p.slice[1].value)
                # XXX TODO : lineno. and position in error message
                print(
                    'SyntaxError: Unary operator "{}" not applicable '
                    "at position {}".format(p[1][0], position)
                )
                exit(1)
            p[0] = GoUnaryExpr(p[2], p[1][0])
            p[0].lineno = adjust_lineno(p[1][1])
Ejemplo n.º 2
0
def p_InterfaceType(p):
    """InterfaceType : INTERFACE LCURLBR MethodSpecList RCURLBR
    """
    try:
        p[0] = GoInterfaceType(p[3])
    except ValueError as msg:
        position = go_traceback(p.slice[1])
        print("{} at position {}".format(msg, position))
        exit(1)
Ejemplo n.º 3
0
def p_StructType(p):
    """StructType : STRUCT LCURLBR FieldDeclList RCURLBR
    """
    try:
        p[0] = GoStruct(p[3])
        p[0].lineno = adjust_lineno(p.slice[1].lineno)
    except ValueError as msg:
        position = go_traceback(p.slice[1])
        print("{} at position {}".format(msg, position))
        exit(1)
Ejemplo n.º 4
0
def p_Expression(p):
    """Expression : UnaryExpr
                  | Expression LOGOR Expression
                  | Expression LOGAND Expression
                  | Expression EQUALS Expression
                  | Expression NOTEQ Expression
                  | Expression LESS Expression
                  | Expression LESSEQ Expression
                  | Expression GREAT Expression
                  | Expression GREATEQ Expression
                  | Expression PLUS Expression
                  | Expression MINUS Expression
                  | Expression BITOR Expression
                  | Expression BITXOR Expression
                  | Expression MULT Expression
                  | Expression DIV Expression
                  | Expression MODULO Expression
                  | Expression LSHIFT Expression
                  | Expression RSHIFT Expression
                  | Expression BITAND Expression
                  | Expression BITCLR Expression
    """
    if len(p) == 2:  # UnaryExpr given
        p[0] = p[1]
    else:
        if isinstance(p[1], GoBasicLit) and isinstance(p[3], GoBasicLit):
            # Direct calculation
            error = False
            try:
                p[0] = GoBasicLit(p[1].item, None)
                p[0].lineno = adjust_lineno(p.slice[2].lineno)
                if p[2] == "||":
                    if p[1].dtype.name != "bool" or p[3].dtype.name != "bool":
                        error = True
                    else:
                        p[0].item = p[1].item or p[3].item
                elif p[2] == "&&":
                    if p[1].dtype.name != "bool" or p[3].dtype.name != "bool":
                        error = True
                    else:
                        p[0].item = p[1].item and p[3].item
                elif p[2] == "==":
                    p[0].item = p[1].item == p[3].item
                elif p[2] == "!=":
                    p[0].item = p[1].item != p[3].item
                elif p[2] == "<":
                    p[0].item = p[1].item < p[3].item
                elif p[2] == "<=":
                    p[0].item = p[1].item <= p[3].item
                elif p[2] == ">":
                    p[0].item = p[1].item > p[3].item
                elif p[2] == ">=":
                    p[0].item = p[1].item >= p[3].item
                elif p[2] == "+":
                    p[0].item += p[3].item
                elif p[2] == "-":
                    p[0].item -= p[3].item
                elif p[2] == "|":
                    if p[1].dtype.name != "int" or p[3].dtype.name != "int":
                        error = True
                    else:
                        p[0].item |= p[3].item
                elif p[2] == "^":
                    if p[1].dtype.name != "int" or p[3].dtype.name != "int":
                        error = True
                    else:
                        p[0].item ^= p[3].item
                elif p[2] == "*":
                    p[0].item *= p[3].item
                elif p[2] == "/":
                    if p[1].dtype.name == "int" and p[3].dtype.name == "int":
                        p[0].item //= p[3].item
                    else:
                        p[0].item /= p[3].item
                elif p[2] == "%":
                    if p[1].dtype.name != "int" or p[3].dtype.name != "int":
                        error = True
                    else:
                        p[0].item %= p[3].item
                elif p[2] == "<<":
                    if p[1].dtype.name != "int" or p[3].dtype.name != "int":
                        error = True
                    else:
                        p[0].item <<= p[3].item
                elif p[2] == ">>":
                    if p[1].dtype.name != "int" or p[3].dtype.name != "int":
                        error = True
                    else:
                        p[0].item >>= p[3].item
                elif p[2] == "&":
                    if p[1].dtype.name != "int" or p[3].dtype.name != "int":
                        error = True
                    else:
                        p[0].item &= p[3].item
                elif p[2] == "&^":
                    if p[1].dtype.name != "int" or p[3].dtype.name != "int":
                        error = True
                    else:
                        p[0].item &= ~p[3].item
                else:
                    error = True

                precedence = ["complex", "float", "int"]
                if p[2] in [">", "<", "==", "!=", ">=", "<="]:
                    p[0].dtype = GoType(
                        "bool", p[1].dtype.basic_lit & p[3].dtype.basic_lit
                    )
                elif p[1].dtype == p[3].dtype or precedence.index(
                    p[1].dtype.name
                ) < precedence.index(p[3].dtype.name):
                    p[0].dtype = p[1].dtype
                else:
                    p[0].dtype = p[3].dtype

            except Exception:
                error = True

            if error:
                go_traceback("")
                print(
                    'SyntaxError: Binary operator "{}" not applicable for '
                    'arguments of types "{}" and "{}"'.format(
                        p[2], p[1].dtype.name, p[3].dtype.name
                    )
                )
                exit(1)
        else:
            # 1st arg. is LHS, 2nd is RHS, 3rd is the operator
            p[0] = GoExpression(p[1], p[3], p[2])
            p[0].lineno = adjust_lineno(p.slice[2].lineno)