Example #1
0
    def get_number(self):
        result = self.character

        self.advance()

        while self.character != None and self.character.isdigit():
            result += self.character

            self.advance()

        if self.character == '.':
            result += '.'

            self.advance()

            if self.character == None or not self.character.isdigit():
                self.gen_position()
                error.highlight(self.position)
                print("Error: expected digit after the dot")

                exit()

            while self.character != None and self.character.isdigit():
                result += self.character

                self.advance()

        return result
Example #2
0
    def parse_stmts(self):
        if self.token.type != TokenType.LEFT_ROUND_BRACKET:
            return self.parse_stmt()

        result = StmtsNode([self.advance()], [])

        self.skip_newlines()

        if self.token.type != TokenType.RIGHT_ROUND_BRACKET:
            result.nodes.append(self.parse_stmt())

        while self.token.type == TokenType.NEWLINE:
            self.skip_newlines()

            if self.token.type == TokenType.RIGHT_ROUND_BRACKET:
                break

            result.nodes.append(self.parse_stmt())

        if self.token.type != TokenType.RIGHT_ROUND_BRACKET:
            error.highlight(self.token.position)
            print(
                "Error: expected a `)` or a newline while parsing statements")
            exit()

        result.tokens.append(self.advance())

        return result
Example #3
0
    def parse_array(self):
        if self.token.type != TokenType.LEFT_SQUARE_BRACKET:
            error.highlight(self.token.position)
            print("Error: expected a `[` while parsing an array")
            exit()

        result = ArrayNode([self.advance()], [])

        self.skip_newlines()

        if self.token.type != TokenType.RIGHT_SQUARE_BRACKET:
            result.nodes.append(self.parse_expr())

        while self.token.type in [TokenType.COMMA, TokenType.NEWLINE]:
            self.advance()
            self.skip_newlines()

            if self.token.type == TokenType.RIGHT_SQUARE_BRACKET:
                break

            result.nodes.append(self.parse_expr())

        if self.token.type != TokenType.RIGHT_SQUARE_BRACKET:
            error.highlight(self.token.position)
            print("Error: expected a `]` while parsing an array")
            exit()

        result.nodes.append(self.advance())

        return result
Example #4
0
    def parse_type_struct(self):
        if self.token.type != TokenType.LEFT_CURLY_BRACKET:
            error.highlight(self.token.position)
            print("Error: expected a `{` while parsing struct type")
            exit()

        result = StructTypeNode([self.advance()], [])

        self.skip_newlines()

        if self.token.type != TokenType.RIGHT_CURLY_BRACKET:
            result.fields.append(self.parse_anon_field())

        while self.token.type in [TokenType.COMMA, TokenType.NEWLINE]:
            self.advance()
            self.skip_newlines()

            if self.token.type == TokenType.RIGHT_CURLY_BRACKET:
                break

            result.fields.append(self.parse_anon_field())

        if self.token.type != TokenType.RIGHT_CURLY_BRACKET:
            error.highlight(self.token.position)
            print("Error: expected a `}` while parsing struct type")
            exit()

        result.tokens.append(self.advance())

        return result
Example #5
0
    def parse_oper1(self):
        result = self.parse_oper0()

        while self.token.type in [
                TokenType.ASTERISK, TokenType.SLASH, TokenType.PERCENT,
                TokenType.SHIFT_LEFT, TokenType.SHIFT_RIGHT
        ]:
            if self.token.type == TokenType.ASTERISK:
                result = MulNode([self.advance()],
                                 [result, self.parse_oper0()])
            elif self.token.type == TokenType.SLASH:
                result = DivNode([self.advance()],
                                 [result, self.parse_oper0()])
            elif self.token.type == TokenType.PERCENT:
                result = ModNode([self.advance()],
                                 [result, self.parse_oper0()])
            elif self.token.type == TokenType.SHIFT_LEFT:
                result = ShlNode([self.advance()],
                                 [result, self.parse_oper0()])
            elif self.token.type == TokenType.SHIFT_RIGHT:
                result = ShrNode([self.advance()],
                                 [result, self.parse_oper0()])
            else:
                error.highlight(self.token.position)
                print("Error: internal error")
                exit()

        return result
Example #6
0
    def parse_while(self):
        if self.token.type != TokenType.WHILE:
            error.highlight(self.token.position)
            print("Error: expected a `while` while parsing an while statement")
            exit()

        return WhileNode(
            [self.advance()],
            [self.parse_expr(), self.parse_stmts()])
Example #7
0
    def parse_type_array(self):
        if self.token.type != TokenType.LEFT_SQUARE_BRACKET:
            error.highlight(self.token.position)
            print("Error: expected a `[` while parsing array type")
            exit()

        result = ArrayTypeNode([self.advance()], self.parse_type())

        if self.token.type != TokenType.RIGHT_SQUARE_BRACKET:
            error.highlight(self.token.position)
            print("Error: expected a `]` while parsing array type")
            exit()

        result.tokens.append(self.advance())

        return result
Example #8
0
    def parse_oper2(self):
        result = self.parse_oper1()

        while self.token.type in [TokenType.PLUS, TokenType.MINUS]:
            if self.token.type == TokenType.PLUS:
                result = AddNode([self.advance()],
                                 [result, self.parse_oper1()])
            elif self.token.type == TokenType.MINUS:
                result = SubNode([self.advance()],
                                 [result, self.parse_oper1()])
            else:
                error.highlight(self.token.position)
                print("Error: internal error")
                exit()

        return result
Example #9
0
    def parse_if(self):
        if self.token.type != TokenType.IF:
            error.highlight(self.token.position)
            print("Error: expected a `if` while parsing an if statement")
            exit()

        result = IfNode(
            [self.advance()],
            [self.parse_expr(), self.parse_stmts()])

        if self.token.type != TokenType.ELSE:
            return result

        result.tokens.append(self.advance())
        result.nodes.append(self.parse_stmts())

        return result
Example #10
0
    def parse_prgrm(self):
        result = PrgrmNode([], [])

        self.skip_newlines()

        if self.token.type != TokenType.EOF:
            result.nodes.append(self.parse_stmt())

        while self.token.type == TokenType.NEWLINE:
            self.skip_newlines()

            if self.token.type == TokenType.EOF:
                break

            result.nodes.append(self.parse_stmt())

        if self.token.type != TokenType.EOF:
            error.highlight(self.token.position)
            print("Error: expected EOF while parsing program")
            exit()

        return result
Example #11
0
    def parse_oper3(self):
        result = self.parse_oper2()

        while self.token.type in [
                TokenType.BITWISE_OR, TokenType.BITWISE_AND,
                TokenType.BITWISE_XOR
        ]:
            if self.token.type == TokenType.BITWISE_OR:
                result = BitOrNode([self.advance()],
                                   [result, self.parse_oper2()])
            elif self.token.type == TokenType.BITWISE_AND:
                result = BitAndNode([self.advance()],
                                    [result, self.parse_oper2()])
            elif self.token.type == TokenType.BITWISE_XOR:
                result = BitXorNode([self.advance()],
                                    [result, self.parse_oper2()])
            else:
                error.highlight(self.token.position)
                print("Error: internal error")
                exit()

        return result
Example #12
0
    def parse_factor(self):
        if self.token.type == TokenType.NUMBER:
            result = NumNode([self.advance()])
        elif self.token.type == TokenType.IDENTIFIER:
            result = IdenNode([self.advance()])
        elif self.token.type == TokenType.LEFT_SQUARE_BRACKET:
            result = self.parse_array()
        elif self.token.type == TokenType.LEFT_CURLY_BRACKET:
            result = self.parse_struct()
        elif self.token.type == TokenType.LEFT_ROUND_BRACKET:
            result = self.parse_stmts()
        elif self.token.type in [
                TokenType.VAR, TokenType.CON, TokenType.IF, TokenType.WHILE
        ]:
            result = self.parse_stmt()
        else:
            error.highlight(self.token.position)
            print("Error: expected a number or identifier")
            exit()

        # call or index
        while self.token.type in [
                TokenType.LEFT_SQUARE_BRACKET, TokenType.LEFT_CURLY_BRACKET
        ]:
            if self.token.type == TokenType.LEFT_SQUARE_BRACKET:
                result = IndexNode([self.advance()], [result])
                result.nodes.append(self.parse_expr())

                if self.token.type != TokenType.RIGHT_SQUARE_BRACKET:
                    error.highlight(self.token.position)
                    print("Error: expected `]` while parsing index")
                    exit()

                result.tokens.append(self.advance())
            elif self.token.type == TokenType.LEFT_CURLY_BRACKET:
                result = CallNode([], [result, self.parse_struct()])

        return result
Example #13
0
    def parse_decl_func(self):
        if self.token.type != TokenType.FUNC:
            error.highlight(self.token.position)
            print("Error: expected a `func` while parsing a func decleration")
            exit()

        result = DeclFuncNode([self.advance()], [None, None, None])

        if self.token.type != TokenType.IDENTIFIER:
            error.highlight(self.token.position)
            print(
                "Error: expected an identifier while parsing a func decleration"
            )
            exit()

        result.tokens.append(self.advance())

        if self.token.type in [
                TokenType.TYPE_IDENTIFIER, TokenType.LEFT_CURLY_BRACKET
        ]:
            result.nodes[0] = self.parse_type()

        if self.token.type == TokenType.TO:
            result.tokens.append(self.advance())

            if not self.token.type in [
                    TokenType.TYPE_IDENTIFIER, TokenType.LEFT_CURLY_BRACKET
            ]:
                error.highlight(self.token.position)
                print(
                    "Error: expected a type while parsing a func decleration")
                exit()

            result.nodes[1] = self.parse_type()

        result.nodes[2] = self.parse_stmts()

        return result
Example #14
0
    def parse_con(self):
        if self.token.type != TokenType.CON:
            error.highlight(self.token.position)
            print("Error: expected a `con` while parsing a con statemnt")
            exit()

        result = ConNode([self.advance()], [])

        if self.token.type != TokenType.IDENTIFIER:
            error.highlight(self.token.position)
            print("Error: expected an identifier while parsing a con statemnt")
            exit()

        result.tokens.append(self.advance())

        if self.token.type != TokenType.SET:
            error.highlight(self.token.position)
            print("Error: expected a `=` while parsing a con statemnt")
            exit()

        result.tokens.append(self.advance())
        result.nodes.append(self.parse_expr())

        return result
Example #15
0
    def get_token(self):
        if self.character == None:
            return self.gen_token('', TokenType.EOF)

        while self.character in [' ', '\t']:
            self.advance()

        if self.character == '#':
            while self.character != '\n':
                self.advance()

        self.position = Position(self.source, self.pos, None, self.col, None,
                                 self.line, None)

        if self.character.isdigit():
            return self.gen_token(self.get_number(), TokenType.NUMBER)

        if self.character.isalpha() and self.character.islower():
            identifier = self.get_identifier()

            return self.gen_token(
                identifier,
                {
                    "func": TokenType.FUNC,
                    "struct": TokenType.STRUCT,
                    "enum": TokenType.ENUM,
                    "con": TokenType.CON,
                    "var": TokenType.VAR,
                    "if": TokenType.IF,
                    "else": TokenType.ELSE,
                    "while": TokenType.WHILE,
                    # types
                    "u8": TokenType.TYPE_IDENTIFIER,
                    "u16": TokenType.TYPE_IDENTIFIER,
                    "u32": TokenType.TYPE_IDENTIFIER,
                    "u64": TokenType.TYPE_IDENTIFIER,
                    "i8": TokenType.TYPE_IDENTIFIER,
                    "i16": TokenType.TYPE_IDENTIFIER,
                    "i32": TokenType.TYPE_IDENTIFIER,
                    "i64": TokenType.TYPE_IDENTIFIER,
                    "f16": TokenType.TYPE_IDENTIFIER,
                    "f32": TokenType.TYPE_IDENTIFIER,
                    "f64": TokenType.TYPE_IDENTIFIER,
                    "f80": TokenType.TYPE_IDENTIFIER,
                    "uint": TokenType.TYPE_IDENTIFIER,
                    "int": TokenType.TYPE_IDENTIFIER
                }.get(identifier, TokenType.IDENTIFIER))

        if self.character.isalpha() and self.character.isupper():
            return self.gen_token(self.get_identifier(),
                                  TokenType.TYPE_IDENTIFIER)

        if self.character == '+':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('+=', TokenType.SET_PLUS)

            return self.gen_token('+', TokenType.PLUS)
        if self.character == '-':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('-=', TokenType.SET_MINUS)
            if self.character == '>':
                self.advance()

                return self.gen_token('->', TokenType.TO)

            return self.gen_token('-', TokenType.MINUS)
        if self.character == '*':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('*=', TokenType.SET_ASTERISK)

            return self.gen_token('*', TokenType.ASTERISK)
        if self.character == '/':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('/=', TokenType.SET_SLASH)

            return self.gen_token('/', TokenType.SLASH)
        if self.character == '%':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('%=', TokenType.SET_PERCENT)

            return self.gen_token('%', TokenType.PERCENT)
        if self.character == '|':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('|=', TokenType.SET_BITWISE_OR)
            if self.character == '|':
                self.advance()

                return self.gen_token('||', TokenType.OR)

            return self.gen_token('|', TokenType.BITWISE_OR)
        if self.character == '&':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('&=', TokenType.SET_BITWISE_AND)
            if self.character == '&':
                self.advance()

                return self.gen_token('&&', TokenType.AND)

            return self.gen_token('&', TokenType.BITWISE_AND)
        if self.character == '^':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('^=', TokenType.SET_BITWISE_XOR)

            return self.gen_token('^', TokenType.BITWISE_XOR)

        if self.character == '=':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('==', TokenType.EQUAL)

            return self.gen_token('=', TokenType.SET)

        if self.character == '!':
            self.advance()

            if self.character == '=':
                self.advance()

                return self.gen_token('!=', TokenType.NOT_EQUAL)

            return self.gen_token('!', TokenType.NOT)

        if self.character == '<':
            self.advance()

            if self.character == '<':
                self.advance()

                if self.character == '=':
                    self.advance()

                    return self.gen_token('<<=', TokenType.SET_SHIFT_LEFT)

                return self.gen_token('<<', TokenType.SHIFT_LEFT)
            if self.character == '=':
                self.advance()

                return self.gen_token('<=', TokenType.LESS_THAN_OR_EQUAL)

            return self.gen_token('<', TokenType.LESS_THAN)
        if self.character == '>':
            self.advance()

            if self.character == '>':
                self.advance()

                if self.character == '=':
                    self.advance()

                    return self.gen_token('>>=', TokenType.SET_SHIFT_RIGHT)

                return self.gen_token('>>', TokenType.SHIFT_RIGHT)
            if self.character == '=':
                self.advance()

                return self.gen_token('>=', TokenType.GREATER_THAN_OR_EQUAL)

            return self.gen_token('>', TokenType.GREATER_THAN)

        if self.character == '(':
            self.advance()

            return self.gen_token('(', TokenType.LEFT_ROUND_BRACKET)
        if self.character == ')':
            self.advance()

            return self.gen_token(')', TokenType.RIGHT_ROUND_BRACKET)
        if self.character == '[':
            self.advance()

            return self.gen_token('[', TokenType.LEFT_SQUARE_BRACKET)
        if self.character == ']':
            self.advance()

            return self.gen_token(']', TokenType.RIGHT_SQUARE_BRACKET)
        if self.character == '{':
            self.advance()

            return self.gen_token('{', TokenType.LEFT_CURLY_BRACKET)
        if self.character == '}':
            self.advance()

            return self.gen_token('}', TokenType.RIGHT_CURLY_BRACKET)

        if self.character == ',':
            self.advance()

            return self.gen_token(',', TokenType.COMMA)
        if self.character == '.':
            self.advance()

            return self.gen_token('.', TokenType.DOT)
        if self.character == ':':
            self.advance()

            return self.gen_token(':', TokenType.COMMA)

        if self.character == '\n':
            self.advance()

            return self.gen_token('', TokenType.NEWLINE)

        self.position.pos_end = self.pos
        self.position.col_end = self.col
        self.position.line_end = self.line

        error.highlight(self.position)
        print("Error: invalid character")

        exit()