mirror of
				https://git.sfja.dk/Mikkel/slige.git
				synced 2025-10-30 23:28:16 +00:00 
			
		
		
		
	test program works
This commit is contained in:
		
							parent
							
								
									ce91126cb1
								
							
						
					
					
						commit
						2fbccd0bc8
					
				| @ -63,7 +63,7 @@ auto compile_asm(const std::vector<AsmLine>& lines) -> std::vector<uint32_t> | |||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             case AsmLineType::Loc: { |             case AsmLineType::Loc: { | ||||||
|                 locs.insert_or_assign(std::get<Loc>(line.value).value, ip + 1); |                 locs.insert_or_assign(std::get<Loc>(line.value).value, ip); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             case AsmLineType::Ref: { |             case AsmLineType::Ref: { | ||||||
| @ -75,9 +75,15 @@ auto compile_asm(const std::vector<AsmLine>& lines) -> std::vector<uint32_t> | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     for (size_t i = 0; i < output.size(); ++i) { |     for (size_t i = 0; i < output.size(); ++i) { | ||||||
|         if (refs.contains(i)) { |         if (!refs.contains(i)) { | ||||||
|             output.at(i) = static_cast<uint32_t>(locs.at(refs.at(i))); |             continue; | ||||||
|         } |         } | ||||||
|  |         if (!locs.contains(refs.at(i))) { | ||||||
|  |             std::cerr << std::format( | ||||||
|  |                 "error: label \"{}\" used at {} not defined\n", refs.at(i), i); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         output.at(i) = static_cast<uint32_t>(locs.at(refs.at(i))); | ||||||
|     } |     } | ||||||
|     return output; |     return output; | ||||||
| } | } | ||||||
| @ -92,19 +98,23 @@ int main() | |||||||
|     //      + a b
 |     //      + a b
 | ||||||
|     //  }
 |     //  }
 | ||||||
|     //
 |     //
 | ||||||
|     //  let result = 0;
 |     //  fn main() {
 | ||||||
|     //  let i = 0;
 |     //      let result = 0;
 | ||||||
|     //  loop {
 |     //      let i = 0;
 | ||||||
|     //      if i >= 10 {
 |     //      loop {
 | ||||||
|     //          break;
 |     //          if i >= 10 {
 | ||||||
|  |     //              break;
 | ||||||
|  |     //          }
 | ||||||
|  |     //          result = add(result, 5);
 | ||||||
|  |     //          i = + i 1;
 | ||||||
|     //      }
 |     //      }
 | ||||||
|     //      result = add(result, 5);
 |     //      result
 | ||||||
|     //  }
 |     //  }
 | ||||||
|     auto program_asm = std::vector<AsmLine> { |     auto program_asm = std::vector<AsmLine> { | ||||||
|         // clang-format off
 |         // clang-format off
 | ||||||
|         SourceMap,  0, 0, 0, |         SourceMap,  0, 0, 0, | ||||||
|         PushPtr,    R("main"), |         PushPtr,    R("main"), | ||||||
|         Pop, |         Call,       0, | ||||||
|         PushPtr,    R("_exit"), |         PushPtr,    R("_exit"), | ||||||
|         Jump, |         Jump, | ||||||
|         Pop, |         Pop, | ||||||
| @ -112,15 +122,17 @@ int main() | |||||||
|         SourceMap,  19, 2, 5, |         SourceMap,  19, 2, 5, | ||||||
|         Add, |         Add, | ||||||
|         Return, |         Return, | ||||||
|  |         L("main"), | ||||||
|         SourceMap,  28, 5, 1, |         SourceMap,  28, 5, 1, | ||||||
|         PushInt,    0, |         PushInt,    0, | ||||||
|  |         PushInt,    0, | ||||||
|         SourceMap,  44, 6, 1, |         SourceMap,  44, 6, 1, | ||||||
|         PushInt,    0, |         PushInt,    0, | ||||||
|         SourceMap,  55, 7, 1, |         SourceMap,  55, 7, 1, | ||||||
|         L("1"), |         L("0"), | ||||||
|         SourceMap,  66, 8,  5, |         SourceMap,  66, 8,  5, | ||||||
|         LoadLocal,  1, |         LoadLocal,  2, | ||||||
|         PushInt,    0, |         PushInt,    10, | ||||||
|         LessThan, |         LessThan, | ||||||
|         Not, |         Not, | ||||||
|         PushPtr,    R("1"), |         PushPtr,    R("1"), | ||||||
| @ -128,22 +140,25 @@ int main() | |||||||
|         SourceMap,  87, 9, 9, |         SourceMap,  87, 9, 9, | ||||||
|         PushPtr,    R("2"), |         PushPtr,    R("2"), | ||||||
|         Jump, |         Jump, | ||||||
|  |         L("1"), | ||||||
|         SourceMap,  104, 11, 5, |         SourceMap,  104, 11, 5, | ||||||
|         LoadLocal,  0, |         LoadLocal,  1, | ||||||
|         PushInt,    5, |         PushInt,    5, | ||||||
|         PushPtr,    R("add"), |         PushPtr,    R("add"), | ||||||
|         Call,       2, |         Call,       2, | ||||||
|         StoreLocal, 0, |         StoreLocal, 1, | ||||||
|         SourceMap,  133, 12, 5, |         SourceMap,  133, 12, 5, | ||||||
|         LoadLocal,  1, |         LoadLocal,  2, | ||||||
|         PushInt,    1, |         PushInt,    1, | ||||||
|         Add, |         Add, | ||||||
|         StoreLocal, 1, |         StoreLocal, 2, | ||||||
|         PushPtr,    R("0"), |         PushPtr,    R("0"), | ||||||
|         Jump, |         Jump, | ||||||
|         L("2"), |         L("2"), | ||||||
|  |         LoadLocal,  1, | ||||||
|  |         StoreLocal, 0, | ||||||
|  |         Pop, | ||||||
|         Pop, |         Pop, | ||||||
|         PushNull, |  | ||||||
|         Return, |         Return, | ||||||
|         L("_exit"), |         L("_exit"), | ||||||
|         SourceMap,  147, 15, 1 |         SourceMap,  147, 15, 1 | ||||||
| @ -156,6 +171,5 @@ int main() | |||||||
|             .code_coverage = true, |             .code_coverage = true, | ||||||
|         }); |         }); | ||||||
|     vm.run_until_done(); |     vm.run_until_done(); | ||||||
| 
 |     std::cout << std::format("done\n{}\n", vm.stack_repr_string()); | ||||||
|     vm.print_stack(); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
|  | #include <cstdlib> | ||||||
| #include <format> | #include <format> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <string> | #include <string> | ||||||
| @ -50,6 +51,15 @@ struct Ptr { | |||||||
|     uint32_t value; |     uint32_t value; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // clang-format off
 | ||||||
|  | template <ValueType op> struct ValueTypeToType {  }; | ||||||
|  | template <> struct ValueTypeToType<ValueType::Null> { using Type = Null; }; | ||||||
|  | template <> struct ValueTypeToType<ValueType::Int> { using Type = Int; }; | ||||||
|  | template <> struct ValueTypeToType<ValueType::Bool> { using Type = Bool; }; | ||||||
|  | template <> struct ValueTypeToType<ValueType::String> { using Type = String; }; | ||||||
|  | template <> struct ValueTypeToType<ValueType::Ptr> { using Type = Ptr; }; | ||||||
|  | // clang-format on
 | ||||||
|  | 
 | ||||||
| class Value { | class Value { | ||||||
| public: | public: | ||||||
|     Value(Null&& value) |     Value(Null&& value) | ||||||
| @ -80,120 +90,42 @@ public: | |||||||
| 
 | 
 | ||||||
|     inline auto type() const -> ValueType { return m_type; }; |     inline auto type() const -> ValueType { return m_type; }; | ||||||
| 
 | 
 | ||||||
|     inline auto as_null() -> Null& |     template <ValueType VT> inline auto as() -> ValueTypeToType<VT>::Type& | ||||||
|     { |     { | ||||||
|         //
 |  | ||||||
|         try { |         try { | ||||||
|             return std::get<Null>(value); |             return std::get<typename ValueTypeToType<VT>::Type>(value); | ||||||
|         } catch (const std::bad_variant_access& ex) { |         } catch (const std::bad_variant_access& ex) { | ||||||
|             std::cout << std::format("tried to unwrap {} as Null\n", |             std::cerr << std::format("error: tried to unwrap {} as {}\n", | ||||||
|                 value_type_to_string(this->m_type)); |                 value_type_to_string(this->m_type), value_type_to_string(VT)); | ||||||
|             throw; |             std::exit(1); | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     inline auto as_null() const -> const Null& |  | ||||||
|     { |  | ||||||
|         //
 |  | ||||||
|         try { |  | ||||||
|             return std::get<Null>(value); |  | ||||||
|         } catch (const std::bad_variant_access& ex) { |  | ||||||
|             std::cout << std::format("tried to unwrap {} as Null\n", |  | ||||||
|                 value_type_to_string(this->m_type)); |  | ||||||
|             throw; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     inline auto as_int() -> Int& |     template <ValueType VT> | ||||||
|  |     inline auto as() const -> const ValueTypeToType<VT>::Type& | ||||||
|     { |     { | ||||||
|         //
 |  | ||||||
|         try { |         try { | ||||||
|             return std::get<Int>(value); |             return std::get<typename ValueTypeToType<VT>::Type>(value); | ||||||
|         } catch (const std::bad_variant_access& ex) { |         } catch (const std::bad_variant_access& ex) { | ||||||
|             std::cout << std::format("tried to unwrap {} as Int\n", |             std::cerr << std::format("error: tried to unwrap {} as {}\n", | ||||||
|                 value_type_to_string(this->m_type)); |                 value_type_to_string(this->m_type), value_type_to_string(VT)); | ||||||
|             throw; |             std::exit(1); | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     inline auto as_int() const -> const Int& |  | ||||||
|     { |  | ||||||
|         //
 |  | ||||||
|         try { |  | ||||||
|             return std::get<Int>(value); |  | ||||||
|         } catch (const std::bad_variant_access& ex) { |  | ||||||
|             std::cout << std::format("tried to unwrap {} as Int\n", |  | ||||||
|                 value_type_to_string(this->m_type)); |  | ||||||
|             throw; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     inline auto as_bool() -> Bool& |     // clang-format off
 | ||||||
|     { |     inline auto as_null() -> Null& { return as<ValueType::Null>(); } | ||||||
|         //
 |     inline auto as_int() -> Int& { return as<ValueType::Int>(); } | ||||||
|         try { |     inline auto as_bool() -> Bool& { return as<ValueType::Bool>(); } | ||||||
|             return std::get<Bool>(value); |     inline auto as_string() -> String& { return as<ValueType::String>(); } | ||||||
|         } catch (const std::bad_variant_access& ex) { |     inline auto as_ptr() -> Ptr& { return as<ValueType::Ptr>(); } | ||||||
|             std::cout << std::format("tried to unwrap {} as Bool\n", |  | ||||||
|                 value_type_to_string(this->m_type)); |  | ||||||
|             throw; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     inline auto as_bool() const -> const Bool& |  | ||||||
|     { |  | ||||||
|         //
 |  | ||||||
|         try { |  | ||||||
|             return std::get<Bool>(value); |  | ||||||
|         } catch (const std::bad_variant_access& ex) { |  | ||||||
|             std::cout << std::format("tried to unwrap {} as Bool\n", |  | ||||||
|                 value_type_to_string(this->m_type)); |  | ||||||
|             throw; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     inline auto as_string() -> String& |     inline auto as_null() const -> const Null& { return as<ValueType::Null>(); } | ||||||
|     { |     inline auto as_int() const -> const Int& { return as<ValueType::Int>(); } | ||||||
|         //
 |     inline auto as_bool() const -> const Bool& { return as<ValueType::Bool>(); } | ||||||
|         try { |     inline auto as_string() const -> const String& { return as<ValueType::String>(); } | ||||||
|             return std::get<String>(value); |     inline auto as_ptr() const -> const Ptr& { return as<ValueType::Ptr>(); } | ||||||
|         } catch (const std::bad_variant_access& ex) { |     // clang-format on
 | ||||||
|             std::cout << std::format("tried to unwrap {} as String\n", |  | ||||||
|                 value_type_to_string(this->m_type)); |  | ||||||
|             throw; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     inline auto as_string() const -> const String& |  | ||||||
|     { |  | ||||||
|         //
 |  | ||||||
|         try { |  | ||||||
|             return std::get<String>(value); |  | ||||||
|         } catch (const std::bad_variant_access& ex) { |  | ||||||
|             std::cout << std::format("tried to unwrap {} as String\n", |  | ||||||
|                 value_type_to_string(this->m_type)); |  | ||||||
|             throw; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     inline auto as_ptr() -> Ptr& |  | ||||||
|     { |  | ||||||
|         //
 |  | ||||||
|         try { |  | ||||||
|             return std::get<Ptr>(value); |  | ||||||
|         } catch (const std::bad_variant_access& ex) { |  | ||||||
|             std::cout << std::format("tried to unwrap {} as Ptr\n", |  | ||||||
|                 value_type_to_string(this->m_type)); |  | ||||||
|             throw; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     inline auto as_ptr() const -> const Ptr& |  | ||||||
|     { |  | ||||||
|         //
 |  | ||||||
|         try { |  | ||||||
|             return std::get<Ptr>(value); |  | ||||||
|         } catch (const std::bad_variant_access& ex) { |  | ||||||
|             std::cout << std::format("tried to unwrap {} as Ptr\n", |  | ||||||
|                 value_type_to_string(this->m_type)); |  | ||||||
|             throw; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     inline auto to_string() const -> std::string |     inline auto to_string() const -> std::string | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -4,11 +4,70 @@ | |||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
| #include <format> | #include <format> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | #include <string> | ||||||
| #include <utility> | #include <utility> | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| using namespace sliger; | using namespace sliger; | ||||||
| 
 | 
 | ||||||
|  | inline auto maybe_op_to_string(uint32_t value) -> std::string | ||||||
|  | { | ||||||
|  |     switch (static_cast<Op>(value)) { | ||||||
|  |         case Op::Nop: | ||||||
|  |             return "Nop"; | ||||||
|  |         case Op::PushNull: | ||||||
|  |             return "PushNull"; | ||||||
|  |         case Op::PushInt: | ||||||
|  |             return "PushInt"; | ||||||
|  |         case Op::PushBool: | ||||||
|  |             return "PushBool"; | ||||||
|  |         case Op::PushString: | ||||||
|  |             return "PushString"; | ||||||
|  |         case Op::PushPtr: | ||||||
|  |             return "PushPtr"; | ||||||
|  |         case Op::Pop: | ||||||
|  |             return "Pop"; | ||||||
|  |         case Op::LoadLocal: | ||||||
|  |             return "LoadLocal"; | ||||||
|  |         case Op::StoreLocal: | ||||||
|  |             return "StoreLocal"; | ||||||
|  |         case Op::Call: | ||||||
|  |             return "Call"; | ||||||
|  |         case Op::Return: | ||||||
|  |             return "Return"; | ||||||
|  |         case Op::Jump: | ||||||
|  |             return "Jump"; | ||||||
|  |         case Op::JumpIfFalse: | ||||||
|  |             return "JumpIfFalse"; | ||||||
|  |         case Op::Add: | ||||||
|  |             return "Add"; | ||||||
|  |         case Op::Subtract: | ||||||
|  |             return "Subtract"; | ||||||
|  |         case Op::Multiply: | ||||||
|  |             return "Multiply"; | ||||||
|  |         case Op::Divide: | ||||||
|  |             return "Divide"; | ||||||
|  |         case Op::Remainder: | ||||||
|  |             return "Remainder"; | ||||||
|  |         case Op::Equal: | ||||||
|  |             return "Equal"; | ||||||
|  |         case Op::LessThan: | ||||||
|  |             return "LessThan"; | ||||||
|  |         case Op::And: | ||||||
|  |             return "And"; | ||||||
|  |         case Op::Or: | ||||||
|  |             return "Or"; | ||||||
|  |         case Op::Xor: | ||||||
|  |             return "Xor"; | ||||||
|  |         case Op::Not: | ||||||
|  |             return "Not"; | ||||||
|  |         case Op::SourceMap: | ||||||
|  |             return "SourceMap"; | ||||||
|  |         default: | ||||||
|  |             return std::to_string(value); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void VM::run_until_done() | void VM::run_until_done() | ||||||
| { | { | ||||||
|     while (!done()) { |     while (!done()) { | ||||||
| @ -19,15 +78,15 @@ void VM::run_until_done() | |||||||
| void VM::run_n_instructions(size_t amount) | void VM::run_n_instructions(size_t amount) | ||||||
| { | { | ||||||
|     for (size_t i = 0; !done() and i < amount; ++i) { |     for (size_t i = 0; !done() and i < amount; ++i) { | ||||||
|  | 
 | ||||||
|         run_instruction(); |         run_instruction(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void VM::run_instruction() | void VM::run_instruction() | ||||||
| { | { | ||||||
|     std::cout << "stack:\n"; |     std::cout << std::format("    {:>4}: {:<12}{}\n", this->pc, | ||||||
|     this->print_stack(); |         maybe_op_to_string(this->program[this->pc]), stack_repr_string()); | ||||||
|     std::cout << std::format("pc = {}\n", this->pc); |  | ||||||
|     auto op = eat_op(); |     auto op = eat_op(); | ||||||
|     switch (op) { |     switch (op) { | ||||||
|         case Op::Nop: |         case Op::Nop: | ||||||
|  | |||||||
| @ -156,11 +156,18 @@ public: | |||||||
|         return this->stack; |         return this->stack; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     inline void print_stack() const |     inline auto stack_repr_string() const -> std::string | ||||||
|     { |     { | ||||||
|         for (const auto& value : view_stack()) { |         auto result = std::string(); | ||||||
|             std::cout << std::format("    {}\n", value.to_repr_string()); |         result += "→"; | ||||||
|  |         const auto& stack = view_stack(); | ||||||
|  |         for (size_t i = 0; i < stack.size(); ++i) { | ||||||
|  |             if (i != 0) { | ||||||
|  |                 result += " "; | ||||||
|  |             } | ||||||
|  |             result += stack[stack.size() - i - 1].to_repr_string(); | ||||||
|         } |         } | ||||||
|  |         return result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user