From ba639f2bd05f47e08c12198b7b20cd4cf371b25f Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 17 Jul 2018 23:08:13 -0700 Subject: Upgraded core code to latest Nomsu verison. --- examples/how_do_i.nom | 197 ++++++++++++++++++++++++++------------------------ 1 file changed, 103 insertions(+), 94 deletions(-) (limited to 'examples') diff --git a/examples/how_do_i.nom b/examples/how_do_i.nom index 604ea26..e91e9a1 100644 --- a/examples/how_do_i.nom +++ b/examples/how_do_i.nom @@ -1,13 +1,11 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # How do I... # Write a comment? Put a # and go till the end of the line - # How do I write a multi-line comment? After a comment line, any indented text is considered part of the comment (including any deeper-level indented text) The comment ends when the indentation ends - # How do I import a file? use "core/control_flow.nom" @@ -20,6 +18,7 @@ say "Hello world!" # How do I set a variable? %foobar <- 1 %text <- "Hello world" + # Expressions that are more than just literal values require parentheses: %foobar <- (2 + 3) %one-two <- 12 @@ -27,6 +26,7 @@ say %one-two # How do I modify a variable? %foobar <- (%foobar + 1) + # Or, as a shorthand, you can do this to increment a variable: %foobar +<- 1 @@ -38,46 +38,50 @@ say %one-two to the "..". <- E.g. the 2 spaces here will be included as part of the text. But this line will have no leading spaces. - + The text will continue until the indentation ends, skipping trailing newlines. + # How do I put values inside text? (AKA string formatting, string interpolation) 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 + 1, 2 + 1, 3 + 1] 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 - like this: \ will just be treated as a backslash. - + like this: \\ will just be treated as a backslash. + Or, two backlashes will be treated as a single backslash, no matter what follows, like this: \\%foobar <- won't insert any values - - If you need to split a long line without inserting a newline, you can \ - ..end a line with backslash and start the next line with two periods, like that. - - Similarly, you can put a long interpolated indented value like: \ + + If you need to split a long line without inserting a newline, you can end a line \ + ..with backslash and start the next line with two periods, like that. + + Similarly, you can put a long interpolated indented value like: \(..) 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 .. between a backslash and two periods. say "Single-line text can contain escape sequences like \", \\, \n, \065, and \x0A" # How do I define a list? -%my-list <- [1,2,"hello"] +%my-list <- [1, 2, "hello"] + # 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 + 1, 2, 3, 4 + 5, 6 7 - 8,9,10 + 8, 9, 10 # 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" say %my-list.1 + # List entries can be modified like this: %my-list.1 <- "ONE!!!" say (length of %my-list) @@ -95,99 +99,105 @@ say %my-dict.x %my-dict.x <- 9999 # How do I do conditional branching? -if: 1 < 10 +if (1 < 10): say "1 is indeed < 10" - -if: 1 > 10 +if (1 > 10): say "this won't print" -..else +..else: say "this will print" # There's no "elseif", so for longer conditionals, a "when" branch is the best option -when +when: * (3 > 6) * (3 > 5) - * (3 > 4) + * (3 > 4): say "this won't print" - * (3 > 3) + * (3 > 3): say "this won't print" - * (3 > 2) + * (3 > 2): say "this will print" - * else + *else: say "this is the default case" + # How do I do a switch statement? -when 3 = ? +when 3 = ?: * 0 * 1 - * 2 + * 2: say "this won't print" - * 3 + * 3: say "this will print" - * else + *else: say "this won't print" + # How do I loop over a list (a foreach loop)? -%list <- [1,2,3] -for %x in %list +%list <- [1, 2, 3] +for %x in %list: say "For %x loop #\%x" # How do I loop over a number range? # This is inclusive, so it will loop over 1,2, and 3 -for %i in 1 to 3 +for %i in 1 to 3: say "For %i in 1 to 3 loop #\%i" + # This will print 0,2, and 4 -for %even in 0 to 5 by 2 +for %even in 0 to 5 by 2: say "Even #\%even" -for %backwards in 3 to 1 by -1 +for %backwards in 3 to 1 by -1: say "Backwards #\%backwards" # How do I do a 'while' loop? %x <- 1 -repeat while: %x <= 3 +repeat while (%x <= 3): say "repeat while loop #\%x" %x +<- 1 %x <- 1 -repeat until: %x > 3 +repeat until (%x > 3): say "repeat until loop #\%x" %x +<- 1 + # How do I do an infinite loop? %x <- 1 -repeat +repeat: say "repeat loop #\%x" %x +<- 1 - if: %x > 3 + if (%x > 3): stop repeating + # How do I do a 'goto'? -do +do: %x <- 1 === %again === say "GOTO loop #\%x" %x +<- 1 - if: %x <= 3 + if (%x <= 3): go to %again 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: -action [say both %first and also %second] +action [say both %first and also %second]: say %first + # Function arguments are accessed just like variables say %second + # Actions can use "return" to return a value early -action [first fibonacci above %n] +action [first fibonacci above %n]: %f1 <- 0 %f2 <- 1 - repeat + repeat: %tmp <- (%f1 + %f2) %f1 <- %f2 %f2 <- %tmp - if: %f2 > %n + if (%f2 > %n): return %f2 say (first fibonacci above 10) @@ -197,19 +207,18 @@ action [..] I hate %worse-things more than %better-things I think %worse-things are worse than %better-things I like %better-things more than %worse-things -.. +..: say "\(%better-things capitalized) rule and \%worse-things drool!" 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 -action [%what-she-said is what she said] +action [%what-she-said is what she said]: say %what-she-said say "-- she said" @@ -217,122 +226,123 @@ action [%what-she-said is what she said] # The language only reserves []{}().,:;% as special characters, so actions can have really funky names! -action [>> %foo-bar $$$^ --> % @& _~-^-~_~-^ %1 !] +action [>> %foo-bar $$$^ --> % @&_~-^-~_~-^ %1 !]: 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 %こんにちは <- "こんにちは" -action [% と言う] - "\(%)世界" +action [% と言う] "\%世界" say (%こんにちは と言う) # Math and logic operations are just treated the same as actions in the syntax say (2 + 3) + # So you can define your own operators, although they will need to be parenthesized to play nicely with other operators -action [%a ++ %b] - 2 * (%a + %b) +action [%a ++ %b] (2 * (%a + %b)) say (1 ++ (2 * 3)) - # How do I do grouping? # Expressions can be grouped by enclosing parentheses: say (2 + 3) -# Or by an indented region -say + +# Or by (..) followed by an indented region +say (..) 2 + 3 -# Or by ":" until the end of the line -say: 2 + 3 + # If you need to keep going after an indented region, you can start the next line with ".." -say both - "Very long first argument that needs its own line" +say both "Very long first argument that needs its own line" ..and also "short second arg" -action [my favorite number]: 21 + 2 +action [my favorite number] (21 + 2) # This can be nested: -say both +say both (..) my favorite ..number ..and also "foo" - # Macros: # The "lua> %" and "=lua %" macros can be used to write raw lua code: -action [say the time] +action [say the time] (..) lua> ".." - io.write("The OS time is: "..os.time().."\n"); + io.write("The OS time is: ", os.time(), "\\n"); + say the time say "Math expression result is: \(=lua "(1 + 2*3 + 3*4)^2")" # Variables can be accessed via \%varname -action [square root of %n] - =lua "math.sqrt(\%n)" +action [square root of %n] (=lua "math.sqrt(\%n)") say "The square root of 2 is \(square root of 2)" # Macros can be defined to transform one bit of nomsu code into another using "parse % as %": -parse [if %condition is untrue %body] as +parse [if %condition is untrue %body] as (..) if (not %condition) %body # Or to transform nomsu code into custom lua code using "compile % to %" -compile [if %condition on opposite day %body] to +compile [if %condition on opposite day %body] to (..) Lua ".." if not \(%condition as lua expr) then \(%body as lua statements) end + # Constants can be defined as macros -parse [TWENTY] as: 20 +parse [TWENTY] as 20 + # When they're invoked, they'll need parentheses just like a function call -parse [TWENTY ONE] as: 21 +parse [TWENTY ONE] as 21 + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # If you need to use compile-time actions in the same file that they're defined in, you can add a line of tildes (3 or more), and the file will be split into chunks, and each chunk will run before the next one compiles. (note that each chunk has its own scope) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -if (1 > (TWENTY)) is untrue +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 +if (1 > (TWENTY)) on opposite day: 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: -action [best of %items according to %key-fn] - <- {%best:nil, %best-key:nil} - for %item in %items +action [best of %items according to %key-fn]: + <- {%best: nil, %best-key: nil} + for %item in %items: %key <- (=lua "\%key-fn(\%item)") - if: (%best is (nil)) or (%key > %best-key) - <- {%best:%item, %best-key:%key} + if ((%best is (nil)) or (%key > %best-key)): + <- {%best: %item, %best-key: %key} + return %best -say: best of [2,-3,4,-8] according to ([%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: -parse [best of %items where %item-var has score %key-expr] as - result of - <- {%best:nil, %best-key:nil} - for %item-var in %items +parse [best of %items where %item-var has score %key-expr] as (..) + result of: + <- {%best: nil, %best-key: nil} + for %item-var in %items: %key <- %key-expr - if: (%best is (nil)) or (%key > %best-key) - <- {%best:%item-var, %best-key:%key} + if ((%best is (nil)) or (%key > %best-key)): + <- {%best: %item-var, %best-key: %key} + return %best -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -say: best of [2,-3,4,-8] where %x has score (%x * %x) -# The first example generates code that looks like: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +say (best of [2, -3, 4, -8] where %x has score (%x * %x)) +# The first example generates code that looks like: + A_best_of_1_according_to_2 = function(items, key_fn) local best, best_key = nil, nil for _, item in ipairs(items) do @@ -346,9 +356,9 @@ say: best of [2,-3,4,-8] where %x has score (%x * %x) print(A_best_of_1_according_to_2({2,-3,4,-8}, function(x) return x * x end)) - + But the second example produces something more like: - + print((function() local best, best_key = nil, nil for _, x in ipairs({1,-2,3,-4}) do @@ -364,4 +374,3 @@ say: best of [2,-3,4,-8] where %x has score (%x * %x) the code only has to do a multiplication, instead of calling a function that does the multiplication. In addition to being more efficient, it's also more powerful and flexible for the language to allow you to define syntax that manipulates expressions. - -- cgit v1.2.3