about summary refs log tree commit diff stats
path: root/cpp/015jump
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-02-19 18:25:25 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-02-19 18:25:25 -0800
commit201b2e6c7ce94c986fe7888a60f0e1ba24a05ce9 (patch)
tree078579498b5dcbcbfbd07634a5164b68561f3016 /cpp/015jump
parent7ec3e3b41eb404dbca4943d87ff14838e1177469 (diff)
downloadmu-201b2e6c7ce94c986fe7888a60f0e1ba24a05ce9.tar.gz
796 - jump instructions done
Diffstat (limited to 'cpp/015jump')
-rw-r--r--cpp/015jump91
1 files changed, 87 insertions, 4 deletions
diff --git a/cpp/015jump b/cpp/015jump
index bcac4b6c..99b333dd 100644
--- a/cpp/015jump
+++ b/cpp/015jump
@@ -23,10 +23,93 @@ recipe main [
 
 :(scenario "jump_backward")
 recipe main [
-  jump 1:offset
-  jump 1:offset
-  jump -2:offset
-]
+  jump 1:offset  // 0 -+
+  jump 1:offset  //    | 1 +-+
+  jump -2:offset //  2 +-->+ |
+]                //       3 \/
 +run: instruction 0
 +run: instruction 2
 +run: instruction 1
+
+:(before "End Globals")
+const int JUMP_IF = 11;
+:(before "End Primitive Recipe Numbers")
+Recipe_number["jump-if"] = JUMP_IF;
+Next_recipe_number++;
+:(before "End Primitive Recipe Implementations")
+case JUMP_IF: {
+  vector<int> arg0 = read_memory(instructions[pc].ingredients[0]);
+  assert(arg0.size() == 1);
+  trace("run") << "ingredient 0 is " << arg0[0];
+  if (!arg0[0]) {
+    trace("run") << "jump-if fell through";
+    break;
+  }
+  trace("run") << "ingredient 1 is " << instructions[pc].ingredients[1].name;
+  pc += to_int(instructions[pc].ingredients[1].name);
+  trace("run") << "jumping to instruction " << pc+1;
+  break;
+}
+
+:(scenario "jump_if")
+recipe main [
+  jump-if 999:literal 1:offset
+  1:integer <- copy 1:literal
+]
++run: instruction 0
++run: ingredient 1 is 1
++run: jumping to instruction 2
+-run: instruction 1
+-mem: storing in location 1
+
+:(scenario "jump_if_fallthrough")
+recipe main [
+  jump-if 0:literal 1:offset
+  123:integer <- copy 1:literal
+]
++run: instruction 0
++run: jump-if fell through
++run: instruction 1
++mem: storing in location 123
+
+:(before "End Globals")
+const int JUMP_UNLESS = 12;
+:(before "End Primitive Recipe Numbers")
+Recipe_number["jump-unless"] = JUMP_UNLESS;
+Next_recipe_number++;
+:(before "End Primitive Recipe Implementations")
+case JUMP_UNLESS: {
+  vector<int> arg0 = read_memory(instructions[pc].ingredients[0]);
+  assert(arg0.size() == 1);
+  trace("run") << "ingredient 0 is " << arg0[0];
+  if (arg0[0]) {
+    trace("run") << "jump-unless fell through";
+    break;
+  }
+  trace("run") << "ingredient 1 is " << instructions[pc].ingredients[1].name;
+  pc += to_int(instructions[pc].ingredients[1].name);
+  trace("run") << "jumping to instruction " << pc+1;
+  break;
+}
+
+:(scenario "jump_unless")
+recipe main [
+  jump-unless 0:literal 1:offset
+  1:integer <- copy 1:literal
+]
++run: instruction 0
++run: ingredient 1 is 1
++run: jumping to instruction 2
+-run: instruction 1
+-mem: storing in location 1
+
+:(scenario "jump_unless_fallthrough")
+recipe main [
+  jump-unless 999:literal 1:offset
+  123:integer <- copy 1:literal
+]
++run: instruction 0
++run: ingredient 0 is 999
++run: jump-unless fell through
++run: instruction 1
++mem: storing in location 123
699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
run = {}

Editor_state = {}

-- called both in tests and real run
function run.initialize_globals()
  -- tests currently mostly clear their own state

  -- blinking cursor
  Cursor_time = 0
end

-- called only for real run
function run.initialize(arg)
  log_new('run')
  if Settings then
    run.load_settings()
  else
    run.initialize_default_settings()
  end

  if #arg > 0 then
    Editor_state.filename = arg[1]
    load_from_disk(Editor_state)
    Text.redraw_all(Editor_state)
    Editor_state.screen_top1 = {line=1, pos=1}
    Editor_state.cursor1 = {line=1, pos=1}
  else
    load_from_disk(Editor_state)
    Text.redraw_all(Editor_state)
  end
  edit.check_locs(Editor_state)



  -- keep a few blank lines around: https://merveilles.town/@akkartik/110084833821965708
  love.window.setTitle('lines.love - '..Editor_state.filename)



  if #arg > 1 then
    print('ignoring commandline args after '..arg[1])
  end

  if rawget(_G, 'jit') then
    jit.off()
    jit.flush()
  end
end

function run.load_settings()
  love.graphics.setFont(love.graphics.newFont(Settings.font_height))
  -- determine default dimensions and flags
  App.screen.width, App.screen.height, App.screen.flags = App.screen.size()
  -- set up desired window dimensions
  App.screen.flags.resizable = true
  App.screen.flags.minwidth = math.min(App.screen.width, 200)
  App.screen.flags.minheight = math.min(App.screen.height, 200)
  App.screen.width, App.screen.height = Settings.width, Settings.height
  App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
  App.screen.move(Settings.x, Settings.y, Settings.displayindex)
  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width-Margin_right, Settings.font_height, math.floor(Settings.font_height*1.3))
  Editor_state.filename = Settings.filename
  Editor_state.screen_top1 = Settings.screen_top
  Editor_state.cursor1 = Settings.cursor
end

function run.initialize_default_settings()
  local font_height = 20
  love.graphics.setFont(love.graphics.newFont(font_height))
  run.initialize_window_geometry(App.width('m'))
  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width-Margin_right)
  Editor_state.font_height = font_height
  Editor_state.line_height = math.floor(font_height*1.3)
  Settings = run.settings()
end

function run.initialize_window_geometry(em_width)
  local os = love.system.getOS()
  if os == 'Android' or os == 'iOS' then
    -- maximizing on iOS breaks text rendering: https://github.com/deltadaedalus/vudu/issues/7
    -- no point second-guessing window dimensions on mobile
    App.screen.width, App.screen.height, App.screen.flags = App.screen.size()
    return
  end
  -- maximize window
  App.screen.resize(0, 0)  -- maximize
  App.screen.width, App.screen.height, App.screen.flags = App.screen.size()
  -- shrink height slightly to account for window decoration
  App.screen.height = App.screen.height-100
  App.screen.width = 40*em_width
  App.screen.flags.resizable = true
  App.screen.flags.minwidth = math.min(App.screen.width, 200)
  App.screen.flags.minheight = math.min(App.screen.height, 200)
  App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
end

function run.resize(w, h)
--?   print(("Window resized to width: %d and height: %d."):format(w, h))
  App.screen.width, App.screen.height = w, h
  Text.redraw_all(Editor_state)
  Editor_state.selection1 = {}  -- no support for shift drag while we're resizing
  Editor_state.right = App.screen.width-Margin_right
  Editor_state.width = Editor_state.right-Editor_state.left
  Text.tweak_screen_top_and_cursor(Editor_state, Editor_state.left, Editor_state.right)
end

function run.file_drop(file)
  -- first make sure to save edits on any existing file
  if Editor_state.next_save then
    save_to_disk(Editor_state)
  end
  -- clear the slate for the new file
  App.initialize_globals()
  Editor_state.filename = file:getFilename()
  file:open('r')
  Editor_state.lines = load_from_file(file)
  file:close()
  Text.redraw_all(Editor_state)
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.cursor1 = {line=1, pos=1}



  -- keep a few blank lines around: https://merveilles.town/@akkartik/110084833821965708
  love.window.setTitle('lines.love - '..Editor_state.filename)



end

function run.draw()
  edit.draw(Editor_state)
end

function run.update(dt)
  Cursor_time = Cursor_time + dt
  edit.update(Editor_state, dt)
end

function run.quit()
  edit.quit(Editor_state)
end

function run.settings()
  if Settings == nil then
    Settings = {}
  end
  if Current_app == 'run' then
    Settings.x, Settings.y, Settings.displayindex = App.screen.position()
  end
  local filename = Editor_state.filename
  if is_relative_path(filename) then
    filename = love.filesystem.getWorkingDirectory()..'/'..filename  -- '/' should work even on Windows
  end
  return {
    x=Settings.x, y=Settings.y, displayindex=Settings.displayindex,
    width=App.screen.width, height=App.screen.height,
    font_height=Editor_state.font_height,
    filename=filename,
    screen_top=Editor_state.screen_top1, cursor=Editor_state.cursor1
  }
end

function run.mouse_press(x,y, mouse_button)
  Cursor_time = 0  -- ensure cursor is visible immediately after it moves
  return edit.mouse_press(Editor_state, x,y, mouse_button)
end

function run.mouse_release(x,y, mouse_button)
  Cursor_time = 0  -- ensure cursor is visible immediately after it moves
  return edit.mouse_release(Editor_state, x,y, mouse_button)
end

function run.mouse_wheel_move(dx,dy)
  Cursor_time = 0  -- ensure cursor is visible immediately after it moves
  return edit.mouse_wheel_move(Editor_state, dx,dy)
end

function run.text_input(t)
  Cursor_time = 0  -- ensure cursor is visible immediately after it moves
  return edit.text_input(Editor_state, t)
end

function run.keychord_press(chord, key)
  Cursor_time = 0  -- ensure cursor is visible immediately after it moves
  return edit.keychord_press(Editor_state, chord, key)
end

function run.key_release(key, scancode)
  Cursor_time = 0  -- ensure cursor is visible immediately after it moves
  return edit.key_release(Editor_state, key, scancode)
end

function width(s)
  return love.graphics.getFont():getWidth(s)
end