This commit is contained in:
Kartik K. Agaram 2015-04-17 11:22:59 -07:00
parent c18e17f22f
commit 2199940af1
21 changed files with 49 additions and 16 deletions

View File

@ -132,10 +132,10 @@ enum primitive_recipes {
MAX_PRIMITIVE_RECIPES,
};
:(code)
// It's all very well to construct recipes out of other recipes, but we need
// to know how to do *something* out of the box. For the following
// recipes there are only codes, no entries in the book, because mu just knows
// what to do for them.
//: It's all very well to construct recipes out of other recipes, but we need
//: to know how to do *something* out of the box. For the following
//: recipes there are only codes, no entries in the book, because mu just knows
//: what to do for them.
void setup_recipes() {
Recipe.clear(); Recipe_number.clear();
Recipe_number["idle"] = IDLE;

View File

@ -1,4 +1,5 @@
//: It's often convenient to express recipes in a textual fashion.
:(scenarios add_recipes)
:(scenario first_recipe)
recipe main [

View File

@ -1,11 +1,10 @@
//: Some instructions can take string literals for convenience.
//: For convenience, some instructions will take literal arrays of characters (strings).
//:
//: Instead of quotes, we'll use [] to delimit strings. That'll reduce the
//: need for escaping since we can support nested brackets. And we can also
//: imagine that 'recipe' might one day itself be defined in mu, doing its own
//: parsing.
//: First extend the mu parser to support string literals.
:(scenario "string_literal")
recipe main [
1:address:array:character <- new [abc def]

View File

@ -1,3 +1,14 @@
//: Once a recipe is loaded, we need to run it.
//:
//: So far we've seen recipes as lists of instructions, and instructions point
//: at other recipes. To kick things off mu needs to know how to run certain
//: 'primitive' recipes. That will then give the ability to run recipes
//: containing these primitives.
//:
//: This layer defines a skeleton with just two primitive recipes: IDLE which
//: does nothing, and COPY, which can copy numbers from one memory location to
//: another. Later layers will add more primitives.
:(scenarios run)
:(scenario copy_literal)
recipe main [
@ -66,6 +77,7 @@ void run(routine rr) {
//: Some helpers.
//: We'll need to override these later as we change the definition of routine.
//: Important that they return referrences into the routine.
inline size_t& running_at(routine& rr) {
return rr.running_at;
}
@ -115,9 +127,8 @@ void load(string filename) {
load("core.mu");
recently_added_recipes.clear(); // freeze everything so it doesn't get cleared by tests
//: helper for tests
:(code)
// helper for tests
void run(string form) {
vector<recipe_number> tmp = add_recipes(form);
transform_all();

View File

@ -1,5 +1,6 @@
//: Arithmetic primitives.
:(before "End Primitive Recipe Declarations")
// Arithmetic ops.
ADD,
:(before "End Primitive Recipe Numbers")
Recipe_number["add"] = ADD;

View File

@ -1,5 +1,6 @@
//: Boolean primitives.
:(before "End Primitive Recipe Declarations")
// Boolean ops.
AND,
:(before "End Primitive Recipe Numbers")
Recipe_number["and"] = AND;

View File

@ -1,5 +1,6 @@
//: Jump primitives.
:(before "End Primitive Recipe Declarations")
// Jump ops.
JUMP,
:(before "End Primitive Recipe Numbers")
Recipe_number["jump"] = JUMP;

View File

@ -1,5 +1,6 @@
//: Comparison primitives.
:(before "End Primitive Recipe Declarations")
// Comparison ops.
EQUAL,
:(before "End Primitive Recipe Numbers")
Recipe_number["equal"] = EQUAL;

View File

@ -1,3 +1,5 @@
//: Allow mu programs to log facts just like we've been doing in C++ so far.
:(scenario "trace")
recipe main [
trace [foo], [this is a trace in mu]

View File

@ -1,4 +1,5 @@
//: Containers contain a fixed number of elements of different types.
:(before "End Mu Types Initialization")
//: We'll use this container as a running example, with two integer elements.
int point = Type_number["point"] = Next_type_number++;

View File

@ -1,5 +1,6 @@
//: Instructions can read from addresses pointing at other locations using the
//: 'deref' property.
:(scenario "copy_indirect")
recipe main [
1:address:integer <- copy 2:literal

View File

@ -1,4 +1,5 @@
//: Arrays contain a variable number of elements of the same type.
:(scenario copy_array)
# Arrays can be copied around with a single instruction just like integers,
# no matter how large they are.

View File

@ -1,4 +1,5 @@
//: So far the recipes we define can't run each other. Let's change that.
//: So far the recipes we define can't run each other. Let's fix that.
:(scenario "calling_recipe")
recipe main [
f
@ -46,7 +47,7 @@ inline vector<instruction>& steps(routine& rr) {
:(replace{} "default:" following "End Primitive Recipe Implementations")
default: {
// not a primitive; try to look for a matching recipe
// not a primitive; try to look up the book of recipes
if (Recipe.find(instructions[pc].operation) == Recipe.end()) {
raise << "undefined operation " << instructions[pc].operation << ": " << instructions[pc].name << '\n';
break;

View File

@ -1,5 +1,6 @@
//: Calls can take ingredients just like primitives. To access a recipe's
//: ingredients, use 'next-ingredient'.
:(scenario "next_ingredient")
recipe main [
f 2:literal

View File

@ -1,4 +1,5 @@
//: Calls can also generate results, using 'reply'.
//: Calls can also generate products, using 'reply'.
:(scenario "reply")
recipe main [
3:integer, 4:integer <- f 2:literal
@ -37,7 +38,7 @@ case REPLY: {
break;
}
//: Results can include containers and exclusive containers, addresses and arrays.
//: Products can include containers and exclusive containers, addresses and arrays.
:(scenario "reply_container")
recipe main [
3:point <- f 2:literal

View File

@ -1,4 +1,5 @@
//: Allow tests to be written in mu files.
:(before "End Types")
struct scenario {
string name;

View File

@ -1,4 +1,5 @@
# tests for 'scenario' in previous layer
scenario first_scenario_in_mu [
run [
1:integer <- add 2:literal, 2:literal

View File

@ -1,3 +1,6 @@
//: Support a scenario [ ... ] form at the top level so we can start creating
//: scenarios in mu just like we do in C++.
:(before "End scenario Fields")
vector<pair<string, string> > trace_checks;
vector<pair<string, string> > trace_negative_checks;

View File

@ -1,4 +1,5 @@
# tests for trace-checking scenario in previous layer
scenario first_scenario_checking_trace [
run [
1:integer <- add 2:literal, 2:literal

View File

@ -2,6 +2,7 @@
//: spaces together. When a variable has a property of /space:1, it looks up
//: the variable in the chained/surrounding space. /space:2 looks up the
//: surrounding space of the surrounding space, etc.
:(scenario "closure")
recipe main [
default-space:address:space <- new location:type, 30:literal
@ -32,6 +33,7 @@ recipe increment-counter [
//: To make this work, compute the recipe that provides names for the
//: surrounding space of each recipe. This must happen before transform_names.
:(before "End Globals")
unordered_map<recipe_number, recipe_number> Surrounding_space;

View File

@ -1,3 +1,5 @@
# Some useful helpers for dealing with strings
recipe string-equal [
default-space:address:space <- new location:type, 30:literal
a:address:array:character <- next-ingredient