Implement comparison operators
This commit is contained in:
		
							
								
								
									
										2
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO
									
									
									
									
									
								
							@@ -15,6 +15,8 @@
 | 
				
			|||||||
- It seems instructions are correctly encoded only if the compiler is running
 | 
					- It seems instructions are correctly encoded only if the compiler is running
 | 
				
			||||||
  on a little endian architecture.
 | 
					  on a little endian architecture.
 | 
				
			||||||
- Merge declaration and definition nodes.
 | 
					- Merge declaration and definition nodes.
 | 
				
			||||||
 | 
					- Pointer.
 | 
				
			||||||
 | 
					- Static array.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Shell
 | 
					# Shell
 | 
				
			||||||
- Persist the history.
 | 
					- Persist the history.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -235,11 +235,13 @@ namespace elna::riscv
 | 
				
			|||||||
    void visitor::visit(source::call_statement *statement)
 | 
					    void visitor::visit(source::call_statement *statement)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::size_t argument_offset{ 0 };
 | 
					        std::size_t argument_offset{ 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (auto& argument : statement->arguments())
 | 
					        for (auto& argument : statement->arguments())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            argument->accept(this);
 | 
					            argument->accept(this);
 | 
				
			||||||
 | 
					            const auto free_register = this->register_in_use ? x_register::a0 : x_register::t0;
 | 
				
			||||||
            this->instructions.push_back(instruction(base_opcode::store)
 | 
					            this->instructions.push_back(instruction(base_opcode::store)
 | 
				
			||||||
                    .s(argument_offset, funct3_t::sw, x_register::sp, x_register::a0));
 | 
					                    .s(argument_offset, funct3_t::sw, x_register::sp, free_register));
 | 
				
			||||||
            argument_offset += 4;
 | 
					            argument_offset += 4;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        relocate(statement->name(), address_t::text);
 | 
					        relocate(statement->name(), address_t::text);
 | 
				
			||||||
@@ -321,19 +323,21 @@ namespace elna::riscv
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        this->register_in_use = true;
 | 
					        this->register_in_use = true;
 | 
				
			||||||
        expression->lhs().accept(this);
 | 
					        expression->lhs().accept(this);
 | 
				
			||||||
 | 
					        auto lhs_stack_position = this->variable_counter * 4;
 | 
				
			||||||
 | 
					        ++this->variable_counter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this->instructions.push_back( // movl %eax, -x(%rbp); where x is a number.
 | 
					        this->instructions.push_back(
 | 
				
			||||||
            instruction(base_opcode::store)
 | 
					            instruction(base_opcode::store)
 | 
				
			||||||
                .s(static_cast<std::uint32_t>(this->variable_counter * 4), funct3_t::sw, x_register::sp, x_register::a0)
 | 
					                .s(static_cast<std::uint32_t>(lhs_stack_position), funct3_t::sw, x_register::sp, x_register::a0)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        auto lhs_stack_position = ++this->variable_counter;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this->register_in_use = false;
 | 
					        this->register_in_use = false;
 | 
				
			||||||
        expression->rhs().accept(this);
 | 
					        expression->rhs().accept(this);
 | 
				
			||||||
 | 
					        this->register_in_use = lhs_register == x_register::a0; // Restore.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         this->instructions.push_back(instruction(base_opcode::load)
 | 
					         this->instructions.push_back(instruction(base_opcode::load)
 | 
				
			||||||
            .i(x_register::a0, funct3_t::lw, x_register::sp,
 | 
					            .i(x_register::a0, funct3_t::lw, x_register::sp,
 | 
				
			||||||
                static_cast<std::int8_t>((lhs_stack_position - 1) * 4))
 | 
					                static_cast<std::int8_t>(lhs_stack_position))
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Calculate the result and assign it to a variable on the stack.
 | 
					        // Calculate the result and assign it to a variable on the stack.
 | 
				
			||||||
@@ -355,6 +359,38 @@ namespace elna::riscv
 | 
				
			|||||||
                this->instructions.push_back(instruction(base_opcode::op)
 | 
					                this->instructions.push_back(instruction(base_opcode::op)
 | 
				
			||||||
                    .r(lhs_register, funct3_t::div, x_register::a0, x_register::t0, funct7_t::muldiv));
 | 
					                    .r(lhs_register, funct3_t::div, x_register::a0, x_register::t0, funct7_t::muldiv));
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					            case source::binary_operator::equals:
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::op)
 | 
				
			||||||
 | 
					                    .r(lhs_register, funct3_t::sub, x_register::a0, x_register::t0, funct7_t::sub));
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::opImm)
 | 
				
			||||||
 | 
					                    .i(lhs_register, funct3_t::sltiu, lhs_register, 1));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case source::binary_operator::not_equals:
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::op)
 | 
				
			||||||
 | 
					                    .r(lhs_register, funct3_t::sub, x_register::a0, x_register::t0, funct7_t::sub));
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::op)
 | 
				
			||||||
 | 
					                    .r(lhs_register, funct3_t::sltu, x_register::zero, lhs_register));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case source::binary_operator::less:
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::op)
 | 
				
			||||||
 | 
					                    .r(lhs_register, funct3_t::sltu, x_register::a0, x_register::t0));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case source::binary_operator::greater_equal:
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::op)
 | 
				
			||||||
 | 
					                    .r(lhs_register, funct3_t::sltu, x_register::t0, x_register::a0));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case source::binary_operator::greater:
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::op)
 | 
				
			||||||
 | 
					                    .r(lhs_register, funct3_t::slt, x_register::a0, x_register::t0));
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::opImm)
 | 
				
			||||||
 | 
					                    .i(lhs_register, funct3_t::xori, lhs_register, 1));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case source::binary_operator::less_equal:
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::op)
 | 
				
			||||||
 | 
					                    .r(lhs_register, funct3_t::slt, x_register::t0, x_register::a0));
 | 
				
			||||||
 | 
					                this->instructions.push_back(instruction(base_opcode::opImm)
 | 
				
			||||||
 | 
					                    .i(lhs_register, funct3_t::xori, lhs_register, 1));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -146,7 +146,8 @@ namespace elna::riscv
 | 
				
			|||||||
        instruction& i(x_register rd, funct3_t funct3, x_register rs1, std::uint32_t immediate);
 | 
					        instruction& i(x_register rd, funct3_t funct3, x_register rs1, std::uint32_t immediate);
 | 
				
			||||||
        instruction& s(std::uint32_t imm, funct3_t funct3, x_register rs1, x_register rs2);
 | 
					        instruction& s(std::uint32_t imm, funct3_t funct3, x_register rs1, x_register rs2);
 | 
				
			||||||
        instruction& b(std::uint32_t imm, funct3_t funct3, x_register rs1, x_register rs2);
 | 
					        instruction& b(std::uint32_t imm, funct3_t funct3, x_register rs1, x_register rs2);
 | 
				
			||||||
        instruction& r(x_register rd, funct3_t funct3, x_register rs1, x_register rs2, funct7_t funct7 = funct7_t::none);
 | 
					        instruction& r(x_register rd, funct3_t funct3, x_register rs1, x_register rs2,
 | 
				
			||||||
 | 
					                funct7_t funct7 = funct7_t::none);
 | 
				
			||||||
        instruction& u(x_register rd, std::uint32_t imm);
 | 
					        instruction& u(x_register rd, std::uint32_t imm);
 | 
				
			||||||
        instruction& j(x_register rd, std::uint32_t imm);
 | 
					        instruction& j(x_register rd, std::uint32_t imm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,9 +73,10 @@ namespace elna::source
 | 
				
			|||||||
            colon,
 | 
					            colon,
 | 
				
			||||||
            when,
 | 
					            when,
 | 
				
			||||||
            then,
 | 
					            then,
 | 
				
			||||||
            _while,
 | 
					            loop,
 | 
				
			||||||
            _do,
 | 
					            _do,
 | 
				
			||||||
            procedure
 | 
					            procedure,
 | 
				
			||||||
 | 
					            comparison_operator
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,13 @@ namespace elna::source
 | 
				
			|||||||
        sum,
 | 
					        sum,
 | 
				
			||||||
        subtraction,
 | 
					        subtraction,
 | 
				
			||||||
        multiplication,
 | 
					        multiplication,
 | 
				
			||||||
        division
 | 
					        division,
 | 
				
			||||||
 | 
					        equals,
 | 
				
			||||||
 | 
					        not_equals,
 | 
				
			||||||
 | 
					        less,
 | 
				
			||||||
 | 
					        greater,
 | 
				
			||||||
 | 
					        less_equal,
 | 
				
			||||||
 | 
					        greater_equal
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class declaration;
 | 
					    class declaration;
 | 
				
			||||||
@@ -280,6 +286,7 @@ namespace elna::source
 | 
				
			|||||||
        std::unique_ptr<expression> parse_factor();
 | 
					        std::unique_ptr<expression> parse_factor();
 | 
				
			||||||
        std::unique_ptr<expression> parse_term();
 | 
					        std::unique_ptr<expression> parse_term();
 | 
				
			||||||
        std::unique_ptr<expression> parse_expression();
 | 
					        std::unique_ptr<expression> parse_expression();
 | 
				
			||||||
 | 
					        std::unique_ptr<expression> parse_condition();
 | 
				
			||||||
        std::unique_ptr<constant_definition> parse_constant_definition();
 | 
					        std::unique_ptr<constant_definition> parse_constant_definition();
 | 
				
			||||||
        std::unique_ptr<procedure_definition> parse_procedure_definition();
 | 
					        std::unique_ptr<procedure_definition> parse_procedure_definition();
 | 
				
			||||||
        std::unique_ptr<declaration> parse_declaration();
 | 
					        std::unique_ptr<declaration> parse_declaration();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -204,7 +204,8 @@ namespace elna::source
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return of() == type::identifier
 | 
					        return of() == type::identifier
 | 
				
			||||||
            || of() == type::term_operator
 | 
					            || of() == type::term_operator
 | 
				
			||||||
            || of() == type::factor_operator;
 | 
					            || of() == type::factor_operator
 | 
				
			||||||
 | 
					            || of() == type::comparison_operator;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool token::is_numeric() const noexcept
 | 
					    bool token::is_numeric() const noexcept
 | 
				
			||||||
@@ -257,12 +258,14 @@ namespace elna::source
 | 
				
			|||||||
                return "«if»";
 | 
					                return "«if»";
 | 
				
			||||||
            case type::then:
 | 
					            case type::then:
 | 
				
			||||||
                return "«then»";
 | 
					                return "«then»";
 | 
				
			||||||
            case type::_while:
 | 
					            case type::loop:
 | 
				
			||||||
                return "«while»";
 | 
					                return "«while»";
 | 
				
			||||||
            case type::_do:
 | 
					            case type::_do:
 | 
				
			||||||
                return "«do»";
 | 
					                return "«do»";
 | 
				
			||||||
            case type::procedure:
 | 
					            case type::procedure:
 | 
				
			||||||
                return "«proc»";
 | 
					                return "«proc»";
 | 
				
			||||||
 | 
					            case type::comparison_operator:
 | 
				
			||||||
 | 
					                return "«comparison_operator»";
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        assert(false);
 | 
					        assert(false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -446,7 +449,7 @@ namespace elna::source
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (word == "while")
 | 
					                else if (word == "while")
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    tokens.emplace_back(token::type::_while, iterator.position());
 | 
					                    tokens.emplace_back(token::type::loop, iterator.position());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (word == "do")
 | 
					                else if (word == "do")
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -477,12 +480,49 @@ namespace elna::source
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                tokens.emplace_back(token::type::term_operator, _operator.c_str(), iterator.position());
 | 
					                tokens.emplace_back(token::type::term_operator, _operator.c_str(), iterator.position());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            else if (*iterator == '/' && iterator + 1 != text_end && *(iterator + 1) == '=')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                tokens.emplace_back(token::type::comparison_operator, "n", iterator.position());
 | 
				
			||||||
 | 
					                ++iterator;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            else if (*iterator == '*' || *iterator == '/')
 | 
					            else if (*iterator == '*' || *iterator == '/')
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                std::string _operator{ *iterator };
 | 
					                std::string _operator{ *iterator };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                tokens.emplace_back(token::type::factor_operator, _operator.c_str(), iterator.position());
 | 
					                tokens.emplace_back(token::type::factor_operator, _operator.c_str(), iterator.position());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            else if (*iterator == '<')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::string _operator;
 | 
				
			||||||
 | 
					                auto operator_position = iterator.position();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (iterator + 1 == text_end || *(iterator + 1) != '=')
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _operator.push_back(*iterator);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ++iterator;
 | 
				
			||||||
 | 
					                    _operator.push_back('l');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                tokens.emplace_back(token::type::comparison_operator, _operator.c_str(), operator_position);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (*iterator == '>')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::string _operator;
 | 
				
			||||||
 | 
					                auto operator_position = iterator.position();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (iterator + 1 == text_end || *(iterator + 1) != '=')
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _operator.push_back(*iterator);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ++iterator;
 | 
				
			||||||
 | 
					                    _operator.push_back('g');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                tokens.emplace_back(token::type::comparison_operator, _operator.c_str(), operator_position);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            else if (*iterator == ':' && iterator + 1 != text_end && *(iterator + 1) == '=')
 | 
					            else if (*iterator == ':' && iterator + 1 != text_end && *(iterator + 1) == '=')
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                tokens.emplace_back(token::type::assignment, iterator.position());
 | 
					                tokens.emplace_back(token::type::assignment, iterator.position());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -262,6 +262,24 @@ namespace elna::source
 | 
				
			|||||||
            case '/':
 | 
					            case '/':
 | 
				
			||||||
                this->m_operator = binary_operator::division;
 | 
					                this->m_operator = binary_operator::division;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					            case '=':
 | 
				
			||||||
 | 
					                this->m_operator = binary_operator::equals;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'n':
 | 
				
			||||||
 | 
					                this->m_operator = binary_operator::not_equals;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case '<':
 | 
				
			||||||
 | 
					                this->m_operator = binary_operator::less;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'l':
 | 
				
			||||||
 | 
					                this->m_operator = binary_operator::less_equal;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case '>':
 | 
				
			||||||
 | 
					                this->m_operator = binary_operator::greater;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'g':
 | 
				
			||||||
 | 
					                this->m_operator = binary_operator::greater_equal;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                throw std::logic_error("Invalid binary operator");
 | 
					                throw std::logic_error("Invalid binary operator");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -442,7 +460,7 @@ namespace elna::source
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            ++iterator;
 | 
					            ++iterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            auto expression = parse_expression();
 | 
					            auto expression = parse_condition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ++iterator;
 | 
					            ++iterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -489,6 +507,38 @@ namespace elna::source
 | 
				
			|||||||
        return term;
 | 
					        return term;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::unique_ptr<expression> parser::parse_condition()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::unique_ptr<expression> lhs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((lhs = parse_expression()) == nullptr)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return lhs;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        unsigned char _operator{ 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (iterator.current().of() == source::token::type::equals)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _operator = '=';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (iterator.current().of() == source::token::type::comparison_operator)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _operator = iterator->identifier()[0];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return lhs;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ++iterator;
 | 
				
			||||||
 | 
					        auto rhs = parse_expression();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (rhs == nullptr)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return nullptr;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return std::make_unique<binary_expression>(std::move(lhs), std::move(rhs), _operator);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::unique_ptr<constant_definition> parser::parse_constant_definition()
 | 
					    std::unique_ptr<constant_definition> parser::parse_constant_definition()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        auto definition_identifier = iterator.advance(token::type::identifier);
 | 
					        auto definition_identifier = iterator.advance(token::type::identifier);
 | 
				
			||||||
@@ -595,7 +645,7 @@ namespace elna::source
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            return parse_if_statement();
 | 
					            return parse_if_statement();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (iterator.current(token::type::_while))
 | 
					        else if (iterator.current(token::type::loop))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return parse_while_statement();
 | 
					            return parse_while_statement();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -618,7 +668,7 @@ namespace elna::source
 | 
				
			|||||||
            ++iterator;
 | 
					            ++iterator;
 | 
				
			||||||
            return call;
 | 
					            return call;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        while ((argument_expression = parse_expression()) != nullptr)
 | 
					        while ((argument_expression = parse_condition()) != nullptr)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            call->arguments().push_back(std::move(argument_expression));
 | 
					            call->arguments().push_back(std::move(argument_expression));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -674,7 +724,7 @@ namespace elna::source
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            return nullptr;
 | 
					            return nullptr;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        auto rvalue = parse_expression();
 | 
					        auto rvalue = parse_condition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (rvalue == nullptr)
 | 
					        if (rvalue == nullptr)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -689,7 +739,7 @@ namespace elna::source
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            return nullptr;
 | 
					            return nullptr;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        auto condition = parse_expression();
 | 
					        auto condition = parse_condition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (condition == nullptr || !iterator.skip(token::type::then))
 | 
					        if (condition == nullptr || !iterator.skip(token::type::then))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -706,11 +756,11 @@ namespace elna::source
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::unique_ptr<while_statement> parser::parse_while_statement()
 | 
					    std::unique_ptr<while_statement> parser::parse_while_statement()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (!iterator.skip(token::type::_while))
 | 
					        if (!iterator.skip(token::type::loop))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return nullptr;
 | 
					            return nullptr;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        auto condition = parse_expression();
 | 
					        auto condition = parse_condition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (condition == nullptr || !iterator.skip(token::type::_do))
 | 
					        if (condition == nullptr || !iterator.skip(token::type::_do))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								tests/expectations/print_equals.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tests/expectations/print_equals.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					t
 | 
				
			||||||
 | 
					f
 | 
				
			||||||
 | 
					t
 | 
				
			||||||
 | 
					f
 | 
				
			||||||
 | 
					f
 | 
				
			||||||
 | 
					t
 | 
				
			||||||
 | 
					t
 | 
				
			||||||
 | 
					f
 | 
				
			||||||
 | 
					t
 | 
				
			||||||
 | 
					f
 | 
				
			||||||
 | 
					f
 | 
				
			||||||
 | 
					t
 | 
				
			||||||
							
								
								
									
										14
									
								
								tests/print_equals.eln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tests/print_equals.eln
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					begin
 | 
				
			||||||
 | 
					  writeb(5 = 5);
 | 
				
			||||||
 | 
					  writeb(5 = 4);
 | 
				
			||||||
 | 
					  writeb(5 /= 4);
 | 
				
			||||||
 | 
					  writeb(5 /= 5);
 | 
				
			||||||
 | 
					  writeb(5 < 4);
 | 
				
			||||||
 | 
					  writeb(4 < 5);
 | 
				
			||||||
 | 
					  writeb(5 >= 4);
 | 
				
			||||||
 | 
					  writeb(4 >= 5);
 | 
				
			||||||
 | 
					  writeb(5 > 4);
 | 
				
			||||||
 | 
					  writeb(4 > 5);
 | 
				
			||||||
 | 
					  writeb(5 <= 4);
 | 
				
			||||||
 | 
					  writeb(4 <= 5)
 | 
				
			||||||
 | 
					end.
 | 
				
			||||||
		Reference in New Issue
	
	Block a user