rewrite compiler, add for/rof support
This commit is contained in:
		
							parent
							
								
									6678dccccd
								
							
						
					
					
						commit
						d97c1a6497
					
				
					 8 changed files with 665 additions and 449 deletions
				
			
		| 
						 | 
					@ -223,22 +223,19 @@ void bench_window::on_add_warrior_dialog_response(int response_id, Gtk::FileChoo
 | 
				
			||||||
    gsize length;
 | 
					    gsize length;
 | 
				
			||||||
    file->load_contents(contents, length);
 | 
					    file->load_contents(contents, length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto w = lib94::compile_warrior(std::string(contents, length));
 | 
					    try {
 | 
				
			||||||
 | 
					      warriors.push_back(lib94::compile_warrior(std::string(contents, length)));
 | 
				
			||||||
    delete contents;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (std::holds_alternative<lib94::warrior *>(w)) {
 | 
					 | 
				
			||||||
      warriors.push_back(std::get<lib94::warrior *>(w));
 | 
					 | 
				
			||||||
      on_click_new_round();
 | 
					      on_click_new_round();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    catch (const lib94::compiler_exception &ex) {
 | 
				
			||||||
    else {
 | 
					      Gtk::MessageDialog *md = new Gtk::MessageDialog(std::string("failed to compile: ") + ex.message + " on line " + std::to_string(ex.line_number));
 | 
				
			||||||
      Gtk::MessageDialog *md = new Gtk::MessageDialog(std::string("Failed to compile: ") + std::get<std::string>(w));
 | 
					 | 
				
			||||||
      md->set_transient_for(*this);
 | 
					      md->set_transient_for(*this);
 | 
				
			||||||
      md->set_modal();
 | 
					      md->set_modal();
 | 
				
			||||||
      md->signal_response().connect([md](int) {delete md;});
 | 
					      md->signal_response().connect([md](int) {delete md;});
 | 
				
			||||||
      md->show();
 | 
					      md->show();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delete contents;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  delete dialog;
 | 
					  delete dialog;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,12 @@ namespace lib94 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::string instruction_to_string(const instruction &instr);
 | 
					  std::string instruction_to_string(const instruction &instr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::variant<warrior *, std::string> compile_warrior(std::string source);
 | 
					  struct compiler_exception : public std::exception {
 | 
				
			||||||
 | 
					    unsigned line_number;
 | 
				
			||||||
 | 
					    std::string message;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  warrior *compile_warrior(std::string source);
 | 
				
			||||||
  bool save_warrior(const warrior &w, const std::filesystem::path &to);
 | 
					  bool save_warrior(const warrior &w, const std::filesystem::path &to);
 | 
				
			||||||
  std::optional<warrior *> load_warrior(const std::filesystem::path &from);
 | 
					  std::optional<warrior *> load_warrior(const std::filesystem::path &from);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1023
									
								
								lib94/warrior.cpp
									
										
									
									
									
								
							
							
						
						
									
										1023
									
								
								lib94/warrior.cpp
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										2
									
								
								makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								makefile
									
										
									
									
									
								
							| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
CPP_ARGS = -std=c++20 -O2 -Wall -Wextra -Iinclude
 | 
					CPP_ARGS = -std=c++20 -O2 -Wall -Wextra -Iinclude -ggdb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GTKMM_CPP_ARGS = $(shell pkg-config --cflags gtkmm-4.0)
 | 
					GTKMM_CPP_ARGS = $(shell pkg-config --cflags gtkmm-4.0)
 | 
				
			||||||
GTKMM_LD_ARGS = $(shell pkg-config --libs gtkmm-4.0)
 | 
					GTKMM_LD_ARGS = $(shell pkg-config --libs gtkmm-4.0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,22 +43,25 @@ int main(int argc, const char **argv) {
 | 
				
			||||||
  file1.close();
 | 
					  file1.close();
 | 
				
			||||||
  file2.close();
 | 
					  file2.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto w1 = lib94::compile_warrior(source1);
 | 
					  lib94::warrior *w1, *w2;
 | 
				
			||||||
  auto w2 = lib94::compile_warrior(source2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (std::holds_alternative<std::string>(w1)) {
 | 
					  try {
 | 
				
			||||||
    std::cout << "error compiling " << argv[1] << ": " << std::get<std::string>(w1) << '\n';
 | 
					    w1 = lib94::compile_warrior(source1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  catch (const lib94::compiler_exception &ex) {
 | 
				
			||||||
 | 
					    std::cout << "error in " << argv[1] << " on line " << ex.line_number << ": " << ex.message << '\n';
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (std::holds_alternative<std::string>(w2)) {
 | 
					  try {
 | 
				
			||||||
    std::cout << "error compiling " << argv[2] << ": " << std::get<std::string>(w2) << '\n';
 | 
					    w2 = lib94::compile_warrior(source1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  catch (const lib94::compiler_exception &ex) {
 | 
				
			||||||
 | 
					    std::cout << "error in " << argv[2] << " on line " << ex.line_number << ": " << ex.message << '\n';
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const lib94::warrior *ws[2];
 | 
					  const lib94::warrior *ws[2] = {w1, w2};
 | 
				
			||||||
  ws[0] = std::get<lib94::warrior *>(w1);
 | 
					 | 
				
			||||||
  ws[1] = std::get<lib94::warrior *>(w2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  print_warrior(ws[0]);
 | 
					  print_warrior(ws[0]);
 | 
				
			||||||
  print_warrior(ws[1]);
 | 
					  print_warrior(ws[1]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,14 +16,14 @@ const lib94::warrior *load_warrior(const char *file) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::string source(std::istreambuf_iterator<char>(stream), {});
 | 
					  std::string source(std::istreambuf_iterator<char>(stream), {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto w = lib94::compile_warrior(source);
 | 
					  try {
 | 
				
			||||||
 | 
					    return lib94::compile_warrior(source);
 | 
				
			||||||
  if (std::holds_alternative<std::string>(w)) {
 | 
					 | 
				
			||||||
    fprintf(stderr, "error compiling %s: %s\n", file, std::get<std::string>(w).c_str());
 | 
					 | 
				
			||||||
    exit(1);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return std::get<lib94::warrior *>(w);
 | 
					  catch (const lib94::compiler_exception &ex) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "error in %s on line %u: %s\n", file, ex.line_number, ex.message.c_str());
 | 
				
			||||||
 | 
					    exit(1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv) {
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,13 +2,7 @@
 | 
				
			||||||
;name Big Nothing
 | 
					;name Big Nothing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start
 | 
					start
 | 
				
			||||||
  nop
 | 
					  for 19
 | 
				
			||||||
  nop
 | 
					    nop
 | 
				
			||||||
  nop
 | 
					  rof
 | 
				
			||||||
  nop
 | 
					 | 
				
			||||||
  nop
 | 
					 | 
				
			||||||
  nop
 | 
					 | 
				
			||||||
  nop
 | 
					 | 
				
			||||||
  nop
 | 
					 | 
				
			||||||
  nop
 | 
					 | 
				
			||||||
  jmp start
 | 
					  jmp start
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,16 +1,20 @@
 | 
				
			||||||
;author Benji Dial
 | 
					;author Benji Dial
 | 
				
			||||||
;name Epson
 | 
					;name Epson
 | 
				
			||||||
 | 
					
 | 
				
			||||||
period equ 10
 | 
					intrascan_period equ 10
 | 
				
			||||||
 | 
					interscan_period equ 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
scan_init equ the_end - (the_end - scan) % period + period
 | 
					;interscan period must divide intrascan period
 | 
				
			||||||
 | 
					;intrascan period must divide 8000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scan_init equ the_end - scan - (the_end - scan) % intrascan_period + intrascan_period
 | 
				
			||||||
 | 
					
 | 
				
			||||||
scan
 | 
					scan
 | 
				
			||||||
  seq.i -period, scan_init
 | 
					  seq.i -intrascan_period, scan_init
 | 
				
			||||||
  jmp found
 | 
					  jmp found
 | 
				
			||||||
 | 
					
 | 
				
			||||||
found_ret
 | 
					found_ret
 | 
				
			||||||
  add.ab #period, scan
 | 
					  add.ab #intrascan_period, scan
 | 
				
			||||||
  seq.ab scan, scan
 | 
					  seq.ab scan, scan
 | 
				
			||||||
  jmp scan
 | 
					  jmp scan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,17 +22,17 @@ found_ret
 | 
				
			||||||
  jmn.a scan, scan
 | 
					  jmn.a scan, scan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clear
 | 
					clear
 | 
				
			||||||
  mov the_end, - 1
 | 
					  mov the_end, scan - interscan_period
 | 
				
			||||||
  sub.ab #2, clear
 | 
					  sub.ab #interscan_period, clear
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  seq.ab #the_end - clear - (the_end - clear) % 2 + 3, clear
 | 
					  seq.ab #scan_add - 1 - clear - (scan_add - 1 - scan) % interscan_period + interscan_period, clear
 | 
				
			||||||
  jmp clear
 | 
					  jmp clear
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mov.ab #-1, clear
 | 
					  mov.ab #scan - interscan_period - clear, clear
 | 
				
			||||||
  jmp clear
 | 
					  jmp clear
 | 
				
			||||||
 | 
					
 | 
				
			||||||
scan_add
 | 
					scan_add
 | 
				
			||||||
  dat 2, period + scan_init + 2
 | 
					  dat interscan_period, intrascan_period + scan_init + interscan_period
 | 
				
			||||||
 | 
					
 | 
				
			||||||
found
 | 
					found
 | 
				
			||||||
  mov bomb, >scan
 | 
					  mov bomb, >scan
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue