about summary refs log blame commit diff stats
path: root/editor/subx.dte
blob: cab7b72db0341dac99c139040aa8eeb7d965e15d (plain) (tree)
1
2
3
4
5
6
7
8
9
10




                                                            




                                                                               



                                 
                                                         



























                             
# Syntax highlighting for https://gitlab.com/craigbarnes/dte
#
# To install this file, symlink it to ~/.dte/syntax/subx
# Then add this line to ~/.dte/rc:
#   ft subx subx

syntax subx

# For improved colorization, add lines like these in your ~/.dte/rc (the
# precise colors here assume the default color scheme in a 256-color terminal):
#   hi subx.comment0 25 underline
#   hi comment 25
#   hi subx.comment2 19
#   hi subx.comment3 245
default comment subx.comment0 subx.comment2 subx.comment3

state start code
    str "# . ." subx.comment3
    str "# ." subx.comment2
    str "# -" subx.comment0
    char # comment
    char '"' string
    eat this

state comment
    char "\n" start
    eat this

state subx.comment0
    char "\n" start
    eat this

state subx.comment2
    char "\n" start
    eat this

state subx.comment3
    char "\n" start
    eat this

state string
    char "\"" start string
    eat this
> 56
57
58
59
60
61
62
63
64
65
66
67
                                                                        







                                       
 






























                                                                             
 
                                                                         
          
                                                       



                                                                          
                                                  


                                                        


                                            
 
 



                                                                           
                 


                                      
 
// So far the recipes we define can't run each other. Let's change that.
:(scenario "calling_recipe")
recipe main [
  f
]
recipe f [
  3:integer <- add 2:literal, 2:literal
]
+mem: storing in location 3

:(before "struct routine {")
// Everytime a recipe runs another, we interrupt it and start running the new
// recipe. When that finishes, we continue this one where we left off.
// This requires maintaining a 'stack' of interrupted recipes or 'calls'.
struct call {
  recipe_number running_recipe;
  size_t pc;
  // End Call Fields
  call(recipe_number r) :running_recipe(r), pc(0) {}
};
typedef stack<call> call_stack;

:(replace{} "struct routine")
struct routine {
  call_stack calls;
  routine(recipe_number r) {
    calls.push(call(r));
  }
};
:(replace{} "inline size_t& running_at(routine& rr)")
inline size_t& running_at(routine& rr) {
  return rr.calls.top().pc;
}
:(replace{} "inline string recipe_name(routine& rr)")
inline string recipe_name(routine& rr) {
  return Recipe[rr.calls.top().running_recipe].name;
}
:(replace{} "inline vector<instruction>& steps(routine& rr)")
inline vector<instruction>& steps(routine& rr) {
  return Recipe[rr.calls.top().running_recipe].steps;
}

:(replace{} "default:" following "End Primitive Recipe Implementations.")
default: {
  // not a primitive; try to look for a matching recipe
  if (Recipe.find(instructions[pc].operation) == Recipe.end()) {
    raise << "undefined operation " << instructions[pc].operation << '\n';
    break;
  }
  rr.calls.push(call(instructions[pc].operation));
  continue;  // not done with caller; don't increment pc
}

:(replace{} "inline bool done(routine& rr)")
inline bool done(routine& rr) {
  return rr.calls.empty();
}

:(before "Running one instruction.")
// when we reach the end of one call, we may reach the end of the one below
// it, and the one below that, and so on
while (running_at(rr) >= steps(rr).size()) {
  rr.calls.pop();
  if (rr.calls.empty()) return;
  // todo: no results returned warning
  ++running_at(rr);
}