aboutsummaryrefslogtreecommitdiff
path: root/examples/how_do_i.nom
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2018-11-06 15:13:55 -0800
committerBruce Hill <bruce@bruce-hill.com>2018-11-06 15:15:14 -0800
commitc8ccbe5f42b5a197010b5ee95491dce5b9bbcbf4 (patch)
treedb2259bad177e558067a7cc2ea09836749242009 /examples/how_do_i.nom
parent0f17c5eb9ac4660f2f969bd1e67af42713e45eac (diff)
Removed utils.lua, simplified some metaprogramming stuff, added native support
for calling functions with (%a %b %c) instead of (call %a with [%b, %c]), renamed _List -> List, _Dict -> Dict, improved example code.
Diffstat (limited to 'examples/how_do_i.nom')
-rw-r--r--examples/how_do_i.nom105
1 files changed, 58 insertions, 47 deletions
diff --git a/examples/how_do_i.nom b/examples/how_do_i.nom
index ec75596..91d1ae3 100644
--- a/examples/how_do_i.nom
+++ b/examples/how_do_i.nom
@@ -16,6 +16,7 @@ use "lib"
say "Hello world!"
# How do I set a variable?
+# Variables have "%" prefix:
%foobar = 1
%text = "Hello world"
@@ -31,7 +32,7 @@ say %one_two
%foobar += 1
# How do I define a mutli-line string?
-# In Nomsu, "strings" are called "text", and multi-line text looks like:
+# In Nomsu, the name "text" is used, rather than "string", and multi-line text looks like:
%mutli_text = "\
..Start with a quote mark and a backslash and an indented "..", then put indented
lines below it. The indented lines will not include the indentation, except when
@@ -47,7 +48,7 @@ say "\
..Text can contain a backslash followed by a variable, list, dict, or parenthesized
expression. This escaped value will be converted to readable text, like so:
The value of %foobar is \%foobar, isn't that nice?
- These are some numbers: \[1 + 1, 2 + 1, 3 + 1]
+ These are some numbers: \[1, 2, 3]
The sum of 2 and 4 is \(2 + 4).
A backslash not followed by any of these, and not at the end of a line
@@ -66,16 +67,16 @@ say "\
say "Single-line text can contain escape sequences like \", \\, \000, and \n"
# How do I define a list?
-%my_list = [1, 2, "hello"]
+%my_list = ["first", "second", "third", 4]
# Really long lists can use [..] followed by a bunch of indented values delimited
by commas and/or newlines
-%my_really_long_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+%my_really_long_list = [..]
+ 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000, 110000
+ 120000, 130000, 140000, 150000, 160000, 170000
# How do I use a list?
-%my_list = ["first item", "second item", "third item"]
-
-# Lists are 1-indexed because they're implemented as Lua tables, so this prints "first item"
+# Lists are 1-indexed because they're implemented as Lua tables, so this prints "first"
say %my_list.1
# List entries can be modified like this:
@@ -86,12 +87,15 @@ say %my_list.1
%my_list::pop
# How do I define a dictionary/hash map?
-%my_dict = {x:99, y:101}
-%my_dict = {x:101, y:2, "99 bottles":99, 653:292}
+ One-word text keys don't need quotes, otherwise the key is an expression.
+ If the expression is more complex than a literal, it needs parentheses:
+%my_dict = {x:101, y:2, "how many bottles":99, 653:292, (5 + 6):11}
# How do I use a dict?
# Dicts are also implemented as Lua tables, so they're accessed and modified the same way as lists
say %my_dict.x
+say %my_dict."how many bottles"
+say %my_dict.653
%my_dict.x = 9999
# How do I do conditional branching?
@@ -104,21 +108,21 @@ if (1 > 10):
say "this will print"
# There's no "elseif", so for longer conditionals, a "when" branch is the best option
-if:
- (3 > 6) (3 > 5) (3 > 4):
- say "this won't print"
+when:
(3 > 3):
say "this won't print"
+ (3 > 6) (3 > 5) (3 > 4):
+ say "this won't print because none of the conditions on the line above are true"
(3 > 2):
say "this will print"
else:
say "this is the default case"
# How do I do a switch statement?
-if 3 is:
- 0 1 2:
+if (1 + 2) is:
+ 0 1:
say "this won't print"
- 3:
+ 2 3:
say "this will print"
else:
say "this won't print"
@@ -159,20 +163,22 @@ repeat:
# How do I do a 'goto'?
do:
%x = 1
- === %again ===
+ === (my loop) ===
say "GOTO loop #\%x"
%x += 1
- if (%x <= 3): go to %again
+ if (%x <= 3): go to (my loop)
say "finished going to"
# How do I define a function/method/procedure?
# In nomsu, they're called "action"s, and they can be declared like this:
(say both %first and also %second) means:
say %first
-
- # Function arguments are accessed just like variables
say %second
+# Actions can have parts of the action's name spread throughout.
+ Everything that's not a literal value is treated as part of the action's name
+say both "Hello" and also "world!"
+
# Actions can use "return" to return a value early
(first fibonacci above %n) means:
%f1 = 0
@@ -196,10 +202,6 @@ say (first fibonacci above 10)
I like "dogs" more than "cats"
I think "chihuahuas" are worse than "corgis"
-# Actions can have parts of the action's name spread throughout.
- Everything that's not a literal value is treated as part of the action's name
-say both "Hello" and also "again!"
-
# Actions can even start with a parameter
(%what_she_said is what she said) means:
say %what_she_said
@@ -207,14 +209,14 @@ say both "Hello" and also "again!"
"Howdy pardner" is what she said
-# The language only reserves []{}().,:;% as special characters, so actions
+# The language only reserves []{}().,:;%#\ as special characters, so actions
can have really funky names!
-(>> %foo_bar $$$^ --> % @&_~-^-~_~-^ %1 !) means:
+(>> %foo_bar $@&' --> % @&_~-^-~_~-^ %1 !) means:
say %foo_bar
say %
say %1
->> "wow" $$$^ --> "so flexible!" @&_~-^-~_~-^ "even numbers can be variables!" !
+>> "wow" $@&' --> "so flexible!" @&_~-^-~_~-^ "even numbers can be variables!" !
# There's also full unicode support
%こんにちは = "こんにちは"
@@ -251,9 +253,9 @@ say both (my favorite number) and also "foo"
lua> "io.write(\"The OS time is: \", os.time(), \"\\n\");"
say the time
-say "Math expression result is: \(=lua "(1 + 2*3 + 3*4)^2")"
+say "Math expression result is: \(=lua "(1 + 2*3 + 3*4)^2 % 5")"
-# Variables can be accessed via \%varname
+# Variables can be accessed via \%var
(square root of %n) means (=lua "math.sqrt(\%n)")
say "The square root of 2 is \(square root of 2)"
@@ -261,11 +263,13 @@ say "The square root of 2 is \(square root of 2)"
(if %condition is untrue %body) parses as (if (not %condition) %body)
# Or to transform nomsu code into custom lua code using "compile % to %"
-(if %condition on opposite day %body) compiles to (..)
- Lua "\
- ..if not \(%condition as lua expr) then
- \(%body as lua statements)
- end"
+(debug only %body) compiles to:
+ if %DEBUG_ENABLED:
+ return (Lua "-- Debug code:\n\(%body as lua statements)")
+ ..else:
+ return (Lua "-- (debug code removed for production)")
+
+%DEBUG_ENABLED = (yes)
# Constants can be defined as macros
(TWENTY) parses as 20
@@ -282,37 +286,44 @@ if (1 > (TWENTY)) is untrue:
say "Nomsu parsing macros work!"
say "It looks like a keyword, but there's no magic here!"
-if (1 > (TWENTY)) on opposite day:
+debug only:
say "Lua compiling macros work!"
- say "It looks like a keyword, but there's no magic here!"
# How do I use an action as a value?
# Well... it's always *possible* to fall back to Lua behavior for something like this:
(best of %items according to %key_fn) means:
- set {%best:nil, %best_key:nil}
+ %best = (nil)
+ %best_key = (nil)
for %item in %items:
- %key = (=lua "\%key_fn(\%item)")
+ %key = (%key_fn %item)
if ((%best is (nil)) or (%key > %best_key)):
- set {%best:%item, %best_key:%key}
+ %best = %item
+ %best_key = %key
return %best
+# Function literals look like: [%x] -> (%x * %x)
say (best of [2, -3, 4, -8] according to ([%x] -> (%x * %x)))
-# But nomsu was mostly designed so that you don't *need* to. Instead of creating a
- one-off function to pass to another function and get called a bunch of times, you
- could use a macro to generate a single block of code that inlines the expression you
- want to use:
-(best of %items where %item_var has score %key_expr) parses as (..)
+# Or, you can use ((foo %)'s meaning) to access the function that gets called by (foo %)
+(%x squared) means (%x * %x)
+say (best of [2, -3, 4, -8] according to ((% squared)'s meaning))
+
+# But nomsu was designed with flexible alternatives that are often better than passing functions.
+ For example, instead of calling a key function on every item, you could instead define a macro
+ that gives you a value based on an inlined expression:
+(best of %items where %item has score %key_expr) parses as (..)
result of:
- set {%best:nil, %best_key:nil}
- for %item_var in %items:
+ %best = (nil)
+ %best_key = (nil)
+ for %item in %items:
%key = %key_expr
if ((%best is (nil)) or (%key > %best_key)):
- set {%best:%item_var, %best_key:%key}
+ %best = %item
+ %best_key = %key
return %best
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-say (best of [2, -3, 4, -8] where %x has score (%x * %x))
+ say (best of [2, -3, 4, -8] where %x has score (%x * %x))