From c8ccbe5f42b5a197010b5ee95491dce5b9bbcbf4 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 6 Nov 2018 15:13:55 -0800 Subject: 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. --- examples/how_do_i.nom | 105 ++++++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 47 deletions(-) (limited to 'examples') 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)) -- cgit v1.2.3