aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2019-01-22 16:15:25 -0800
committerBruce Hill <bruce@bruce-hill.com>2019-01-22 16:16:53 -0800
commitf746ba34d799e6560df1aad1cad15a70b34914d1 (patch)
tree3829ce9bd8469e59d1a51470823d510dc808e1c7 /lib
parenta596195f6cfb6731f1e778e4bc304028ecd9bf08 (diff)
Moved all the text method stuff into text.moon instead of splitting
across string2/containers. Modified the type stuff to output better type names and use (a Dict) and (a List) instead of (Dict) and (List). (Text) now also has a proper constructor. (assume) now also handles a bunch of different assumptions with smart error messages.
Diffstat (limited to 'lib')
-rw-r--r--lib/compatibility/compatibility.nom2
-rw-r--r--lib/core/control_flow.nom2
-rw-r--r--lib/core/errors.nom84
-rw-r--r--lib/core/metaprogramming.nom36
-rw-r--r--lib/core/text.nom2
-rwxr-xr-x[-rw-r--r--]lib/tools/tutorial.nom83
6 files changed, 122 insertions, 87 deletions
diff --git a/lib/compatibility/compatibility.nom b/lib/compatibility/compatibility.nom
index 45ea1d6..b72997e 100644
--- a/lib/compatibility/compatibility.nom
+++ b/lib/compatibility/compatibility.nom
@@ -43,7 +43,7 @@ external:
($t is syntax tree):
$args = []
for $k = $v in $t:
- if ((type of $k) == "a number"):
+ if ((type of $k) == "a Number"):
$args, add (make tree $v)
..else:
$args, add "\($k)=\(make tree $v)"
diff --git a/lib/core/control_flow.nom b/lib/core/control_flow.nom
index 2ad7ec7..bf044d9 100644
--- a/lib/core/control_flow.nom
+++ b/lib/core/control_flow.nom
@@ -485,7 +485,7 @@ test:
$lua =
Lua ("
do
- local _stack_\($var as lua expr) = List{\($structure as lua expr)}
+ local _stack_\($var as lua expr) = a_List{\($structure as lua expr)}
while #_stack_\($var as lua expr) > 0 do
\($var as lua expr) = table.remove(_stack_\($var as lua expr), 1)
\($body as lua)
diff --git a/lib/core/errors.nom b/lib/core/errors.nom
index a84b580..e24c012 100644
--- a/lib/core/errors.nom
+++ b/lib/core/errors.nom
@@ -14,31 +14,67 @@ use "core/control_flow"
))
")
-(assume $condition) compiles to ("
- if not \($condition as lua expr) then
- at_1_fail(\(quote "\($condition.source)"), "Assumption failed: This was not true.")
- end
-")
-
-(assume $a == $b) compiles to ("
- do
- local _a, _b = \($a as lua expr), \($b as lua expr)
- if _a ~= _b then
- at_1_fail(\(quote "\($a.source)"),
- "Assumption failed: This value was "..tostring(_a).." but it was expected to be "..tostring(_b)..".")
- end
- end
-")
+(assume $condition) compiles to:
+ if ($condition.type == "Action"):
+ when $condition.stub is:
+ "1 ==":
+ return
+ LuaCode ("
+ do
+ local _a, _b = \($condition.1 as lua expr), \($condition.3 as lua expr)
+ if _a ~= _b then
+ _a = type_of(_a) == 'Text' and _a:as_lua() or tostring(_a)
+ _b = type_of(_b) == 'Text' and _b:as_lua() or tostring(_b)
+ at_1_fail(\(quote "\($condition.1.source)"),
+ "Assumption failed: This value was ".._a.." but it was expected to be ".._b..".")
+ end
+ end
+ ")
+ "1 !=":
+ return
+ LuaCode ("
+ do
+ local _a, _b = \($condition.1 as lua expr), \($condition.3 as lua expr)
+ if _a == _b then
+ _a = type_of(_a) == 'Text' and _a:as_lua() or tostring(_a)
+ at_1_fail(\(quote "\($condition.1.source)"),
+ "Assumption failed: This value was ".._a.." but it wasn't expected to be.")
+ end
+ end
+ ")
+ "1 >" "1 <" "1 >=" "1 <=":
+ return
+ LuaCode ("
+ do
+ local _a, _b = \($condition.1 as lua expr), \($condition.3 as lua expr)
+ if _a ~= _b then
+ _a = type_of(_a) == 'Text' and _a:as_lua() or tostring(_a)
+ _b = type_of(_b) == 'Text' and _b:as_lua() or tostring(_b)
+ at_1_fail(\(quote "\($condition.1.source)"),
+ "Assumption failed: This value was ".._a..", but it was expected to be \($condition.3)".._b..".")
+ end
+ end
+ ")
+ "1 is":
+ return
+ LuaCode ("
+ do
+ local _ta, _tb = type_of(\($condition.1 as lua expr)), \($condition.3 as lua expr)
+ if _ta ~= _tb then
+ at_1_fail(\(quote "\($condition.1.source)"),
+ "Assumption failed: This value was ".._ta.." but it was expected to be ".._tb..".")
+ end
+ end
+ ")
+ return
+ LuaCode ("
+ if not \($condition as lua expr) then
+ at_1_fail(\(quote "\($condition.source)"), "Assumption failed: This assumption did not hold.")
+ end
+ ")
-(assume $a != $b) compiles to ("
- do
- local _a, _b = \($a as lua expr), \($b as lua expr)
- if _a == _b then
- at_1_fail(\(quote "\($a.source)"),
- "Assumption failed: This value was "..tostring(_a).." but it wasn't expected to be.")
- end
- end
-")
+(assume $a == $b) parses as (assume ($a == $b))
+(assume $a != $b) parses as (assume ($a != $b))
test:
try: fail
diff --git a/lib/core/metaprogramming.nom b/lib/core/metaprogramming.nom
index bfcc0bf..c7d3787 100644
--- a/lib/core/metaprogramming.nom
+++ b/lib/core/metaprogramming.nom
@@ -26,7 +26,8 @@ lua> ("
lua> ("
COMPILE_RULES["1 ->"] = function(\(nomsu environment), _tree, \$args, \$body)
- if \$args and not \$body then \$args, \$body = {}, \$args end
+ if not \$args and not \$body then \$args, \$body = {}, SyntaxTree{type='Action', "do", "nothing"}
+ elseif \$args and not \$body then \$args, \$body = {}, \$args end
local body_lua = SyntaxTree:is_instance(\$body) and \(nomsu environment):compile(\$body) or \$body
if SyntaxTree:is_instance(\$body) and \$body.type ~= "Block" then body_lua:prepend("return ") end
local lua = LuaCode("(function(")
@@ -88,7 +89,7 @@ test:
lua> ("
COMPILE_RULES["1 compiles to"] = function(\(nomsu environment), \(this tree), \$action, \$body)
- local \$args = List{"\(nomsu environment)", "\(this tree)"}
+ local \$args = a_List{"\(nomsu environment)", "\(this tree)"}
if \$body.type == "Text" then
\$body = SyntaxTree{source=\$body.source, type="Action", "Lua", \$body}
end
@@ -121,18 +122,18 @@ lua> ("
at_1_fail(\$actions, "Compile error: This should be a list of actions.")
end
local lua = \(\($actions.1 compiles to $body) as lua)
- local \$args = List{"\(nomsu environment)", "\(this tree)", unpack(\$actions[1]:get_args())}
- local \$compiled_args = List{"\(nomsu environment)", "\(this tree)"};
+ local \$args = a_List{"\(nomsu environment)", "\(this tree)", unpack(\$actions[1]:get_args())}
+ local \$compiled_args = a_List{"\(nomsu environment)", "\(this tree)"};
for i=3,#\$args do \$compiled_args[i] = \(nomsu environment):compile(\$args[i]) end
for i=2,#\$actions do
local alias = \$actions[i]
- local \$alias_args = List{"\(nomsu environment)", "\(this tree)", unpack(alias:get_args())}
+ local \$alias_args = a_List{"\(nomsu environment)", "\(this tree)", unpack(alias:get_args())}
lua:add("\\nCOMPILE_RULES[", alias:get_stub():as_lua(), "] = ")
if \$alias_args == \$args then
lua:add("COMPILE_RULES[", \$actions[1]:get_stub():as_lua(), "]")
else
lua:add("function(")
- local \$compiled_alias_args = List{"\(nomsu environment)", "\(this tree)"};
+ local \$compiled_alias_args = a_List{"\(nomsu environment)", "\(this tree)"};
for i=3,#\$alias_args do \$compiled_alias_args[i] = \(nomsu environment):compile(\$alias_args[i]) end
lua:concat_add(\$compiled_alias_args, ", ")
lua:add(") return COMPILE_RULES[", \$actions[1]:get_stub():as_lua(), "](")
@@ -183,10 +184,10 @@ test:
local first_def = (\$actions[1].type == "MethodCall"
and LuaCode(\(nomsu environment):compile(\$actions[1][1]), ".", \$actions[1]:get_stub():as_lua_id())
or LuaCode(\$actions[1]:get_stub():as_lua_id()))
- local \$args = List(\$actions[1]:get_args())
+ local \$args = a_List(\$actions[1]:get_args())
for i=2,#\$actions do
local alias = \$actions[i]
- local \$alias_args = List(alias:get_args())
+ local \$alias_args = a_List(alias:get_args())
lua:add("\\n")
if alias.type == "MethodCall" then
lua:add(\(nomsu environment):compile(alias[1]), ".", alias:get_stub():as_lua_id())
@@ -392,10 +393,10 @@ external:
external:
(match $tree with $patt) means:
lua> ("
- if \$patt.type == "Var" then return Dict{[\$patt:as_var()]=\$tree} end
+ if \$patt.type == "Var" then return a_Dict{[\$patt:as_var()]=\$tree} end
if \$patt.type == "Action" and \$patt:get_stub() ~= \$tree:get_stub() then return nil end
if #\$patt ~= #\$tree then return nil end
- local matches = Dict{}
+ local matches = a_Dict{}
for \($i)=1,#\$patt do
if SyntaxTree:is_instance(\$tree[\$i]) then
local submatch = \(match $tree.$i with $patt.$i)
@@ -425,6 +426,9 @@ test:
assume ({} is "a Dict")
assume ("" is text)
assume ("" is "Text")
+ assume (5 is "a Number")
+ assume ((->) is "an Action")
+ assume ((yes) is "a Boolean")
assume ("" isn't "a Dict")
external:
@@ -432,14 +436,12 @@ external:
[$ is not text, $ isn't text] all mean (=lua "\(lua type of $) ~= 'string'")
(type of $) means:
lua> ("
+ local mt = getmetatable(\$)
+ if mt and mt.__type then return mt.__type end
+ if \$ == nil then return 'nil' end
local lua_type = \(lua type of $)
- if lua_type == 'string' then return 'Text'
- elseif lua_type == 'nil' then return 'nil'
- elseif lua_type == 'table' or lua_type == 'userdata' then
- local mt = getmetatable(\$)
- if mt and mt.__type then return mt.__type end
- end
- return 'a '..lua_type
+ if lua_type == 'function' then return "an Action" end
+ return 'a '..lua_type:capitalized()
")
($ is $type) parses as ((type of $) == $type)
diff --git a/lib/core/text.nom b/lib/core/text.nom
index a1fcaae..1401cf2 100644
--- a/lib/core/text.nom
+++ b/lib/core/text.nom
@@ -46,7 +46,7 @@ test:
return
Lua ("
(function()
- local \(mangle "comprehension") = List{}
+ local \(mangle "comprehension") = a_List{}
for \($match as lua expr) in (\($text as lua expr)):gmatch(\($patt as lua expr)) do
\(mangle "comprehension")[#\(mangle "comprehension")+1] = \($expr as lua)
end
diff --git a/lib/tools/tutorial.nom b/lib/tools/tutorial.nom
index e8295c2..3cdb10c 100644..100755
--- a/lib/tools/tutorial.nom
+++ b/lib/tools/tutorial.nom
@@ -26,10 +26,10 @@ $lessons = [
# In Nomsu, variables have a "$" prefix, and you can just assign to them
without declaring them first:
$x = 10
- assume $x == 10
+ assume ($x == 10)
# Variables which have not yet been set have the value (nil)
- assume $foobar == (nil)
+ assume ($foobar == (nil))
# Variables can be nameless:
$ = 99
@@ -40,7 +40,7 @@ $lessons = [
# Figure out what value $my_var should have:
$my_var = 100
$my_var = ($my_var + $x + $(my favorite number))
- assume (???) == $my_var
+ assume ($my_var == (???))
lesson "Actions":
# Fix this action so the tests pass, then save and quit.
@@ -48,8 +48,8 @@ $lessons = [
($x doubled) means ((???) * $x)
# Tests:
- assume (2 doubled) == 4
- assume (-5 doubled) == -10
+ assume ((2 doubled) == 4)
+ assume ((-5 doubled) == -10)
lesson "Blocks":
# When you need to do multiple things inside an action, use a block.
@@ -69,17 +69,17 @@ $lessons = [
# Make this action return "big" if its argument
# is bigger than 99, otherwise return "small"
(the size of $n) means:
- if (<your code here>):
+ if (???):
<your code here>
..else:
<your code here>
# Tests:
for $small_number in [0, 1, -5, -999, 99]:
- assume (the size of $small_number) == "small"
+ assume ((the size of $small_number) == "small")
for $big_number in [9999, 100]:
- assume (the size of $big_number) == "big"
+ assume ((the size of $big_number) == "big")
lesson "Loops":
# Fix this action so the tests pass:
@@ -92,14 +92,14 @@ $lessons = [
return $sum
# Tests:
- assume (the sum of [1, 2, 3, 4, 5]) == 15
- assume (the sum of [100, 200]) == 300
+ assume ((the sum of [1, 2, 3, 4, 5]) == 15)
+ assume ((the sum of [100, 200]) == 300)
# You can also loop over a number range like this:
$total = 0
for $i in 1 to 3:
$total = ($total + $i)
- assume (???) == $total
+ assume ($total == (???))
lesson "Variable Scopes":
# Nomsu's variables are local by default, and actions have their own scopes:
@@ -110,17 +110,17 @@ $lessons = [
(do something) means:
# The variable $y is never set in this action, so it has the same value
it has outside this action.
- assume (???) == $y
+ assume ($y == (???))
# $x is set inside this action, and actions have their own scopes.
$x = $y
# What number should $x be here?
- assume (???) == $x
+ assume ($x == (???))
# After running the action, what value should $x have?
do something
- assume (???) == $x
+ assume ($x == (???))
lesson "More Variable Scopes":
# Loops and conditionals do *not* have their own scopes:
@@ -130,13 +130,13 @@ $lessons = [
$z = 2
# After assigning in a conditional, what should $z be?
- assume (???) == $z
+ assume ($z == (???))
for $ in 1 to 1:
# Set $z inside a loop:
$z = 3
# After assigning in a loop, what should $z be?
- assume (???) == $z
+ assume ($z == (???))
lesson "Externals":
# The 'external' block lets you modify variables outside an action:
@@ -146,7 +146,7 @@ $lessons = [
do something
# After running the action that sets $x in an 'external' block, what should $x be?
- assume (???) == $x
+ assume ($x == (???))
lesson "Locals":
# The 'with' block lets you create a local scope for the variables you list:
@@ -157,8 +157,8 @@ $lessons = [
$z = 2
# After setting $y and $z in the 'with [$y]' block, what should $y and $z be?
- assume (???) == $y
- assume (???) == $z
+ assume ($y == (???))
+ assume ($z == (???))
lesson "Failure and Recovery":
$what_happened = "nothing"
@@ -172,7 +172,7 @@ $lessons = [
$what_happened = "success"
# What do you think happened?
- assume (???) == $what_happened
+ assume ($what_happened == (???))
# Note: a 'try' block will silence failures, so this has no effect:
try: fail
@@ -180,11 +180,11 @@ $lessons = [
lesson "Indexing":
# Nomsu uses the "." operator to access things inside an object:
$dictionary = {.dog = "A lovable doofus", .cat = "An internet superstar"}
- assume $dictionary.dog == "A lovable doofus"
- assume (???) == $dictionary.cat
+ assume ($dictionary.dog == "A lovable doofus")
+ assume ($dictionary.cat == (???))
# If you try to access a key that's not in an object, the result is (nil):
- assume (???) == $dictionary.mimsy
+ assume ($dictionary.mimsy == (???))
# $dictionary.dog is just a shorthand for $dictionary."dog".
You may need to use the longer form for strings with spaces:
@@ -195,22 +195,22 @@ $lessons = [
$dictionary.5 = "The number five"
$dictionary.five = 5
$dictionary.myself = $dictionary
- assume (???) == $dictionary.myself
+ assume ($dictionary.myself == (???))
# Lists are similar, but use square brackets ([])
and can only have numbers as keys, starting at 1:
$list = ["first", "second", 999]
- assume $list.1 == "first"
- assume (???) == $list.2
- assume (???) == $list.3
+ assume ($list.1 == "first")
+ assume ($list.2 == (???))
+ assume ($list.3 == (???))
# Hint: 4 should be a missing key
- assume (???) == $list.4
- assume (???) == $list.foobar
+ assume ($list.4 == (???))
+ assume ($list.foobar == (???))
# The "#" action gets the number of items inside something:
- assume (???) == (#$list)
- assume (???) == (#{.x = 10, .y = 20})
+ assume ((#$list) == (???))
+ assume ((#{.x = 10, .y = 20}) == (???))
lesson "Methods":
# The "," is used for method calls, which means calling an action
@@ -218,17 +218,17 @@ $lessons = [
# Lists have an "add" method that puts new items at the end:
$list = [-4, -6, 5]
$list, add 3
- assume $list == [-4, -6, 5, 3]
+ assume ($list == [-4, -6, 5, 3])
$list, add 7
- assume $list == [???]
+ assume ($list == [???])
# Text also has some methods like:
$name = "Harry Tuttle"
- assume ($name, character 7) == "T"
- assume (???) == ($name, with "Tuttle" -> "Buttle")
+ assume (($name, character 7) == "T")
+ assume (($name, with "Tuttle" -> "Buttle") == (???))
# Methods can be chained too:
- assume (???) == ($name, with "Tuttle" -> "Buttle", character 7)
+ assume (($name, with "Tuttle" -> "Buttle", character 7) == (???))
lesson "Object Oriented Programming":
# Object Oriented Programming deals with things that have
@@ -244,17 +244,14 @@ $lessons = [
($self, add $bit) means:
$bits, add $bit
- ($self, length) means:
- # Write some code that returns the total length of all
- the bits on this buffer.
- # Hint: the length operator (#$foo) works on text
- <your code here>
+ # Write a method called ($self, length) that returns the total
+ length of all the bits in the buffer:
+ <your code here>
$b = (a Buffer)
$b, add "xx"
$b, add "yyy"
- assume ($b, length) == 5
- assume ($b, joined) == "xxyyy"
+ assume (($b, length) == 5)
]
command line program with $args: