static int skip_whitespace(struct l2_lexer *lexer) { | static int skip_whitespace(struct l2_lexer *lexer) { | ||||
int nl = 0; | int nl = 0; | ||||
while (is_whitespace(peek_ch(lexer))) { | |||||
int ch = read_ch(lexer); | |||||
if (ch == '\n') { | |||||
while (1) { | |||||
while (is_whitespace(peek_ch(lexer))) { | |||||
int ch = read_ch(lexer); | |||||
if (ch == '\n') { | |||||
nl = 1; | |||||
} | |||||
} | |||||
if (peek_ch(lexer) == '#') { | |||||
nl = 1; | nl = 1; | ||||
while (read_ch(lexer) != '\n'); | |||||
} else { | |||||
break; | |||||
} | } | ||||
} | } | ||||
arr := [10 20 30] | arr := [10 20 30] | ||||
print arr | print arr | ||||
# Lookup into the array with dot-number | |||||
print arr.2 | print arr.2 | ||||
# Assign to an index of the array | |||||
arr.1 = "nope" | arr.1 = "nope" | ||||
print arr | print arr | ||||
# Lookup array values dynamically | |||||
idx := 0 | idx := 0 | ||||
arr := [100 20 30] | arr := [100 20 30] | ||||
print arr.(idx) | print arr.(idx) | ||||
# More complex expressions in the subscript operation | |||||
arr.(+ idx 1) = 50 | arr.(+ idx 1) = 50 | ||||
print arr | print arr | ||||
# Lookup into a temporary | |||||
print [10 20 30].(+ 1 1) | print [10 20 30].(+ 1 1) | ||||
# Lookup into a namespace by atom | |||||
obj := {} | obj := {} | ||||
obj.('hello) = "what's up" | obj.('hello) = "what's up" | ||||
print obj.hello | print obj.hello | ||||
# More complicated expression again | |||||
get-ident := {'foo} | get-ident := {'foo} | ||||
obj.(get-ident()) = 100 | obj.(get-ident()) = 100 | ||||
print obj.foo | print obj.foo |
# Functions return their last expression | |||||
func := { | func := { | ||||
"hello" | "hello" | ||||
} | } | ||||
# Call a function without arguments using () | |||||
print func() | print func() | ||||
# A function, returning a function, with a closure so that it can access | |||||
# variables from outside | |||||
str := "Hello World" | str := "Hello World" | ||||
func := { | func := { | ||||
{ | { | ||||
str | str | ||||
} | } | ||||
} | } | ||||
# func() returns a function, which can be called again with an extra () | |||||
print func()() | print func()() | ||||
func := { | func := { | ||||
{ | { | ||||
# $ is a variable containing the arguments passed to the function, | |||||
# so this nested function sets the global 'str' variable to whatever | |||||
# the function is passed | |||||
str = $.0 | str = $.0 | ||||
} | } | ||||
} | } | ||||
# func() calls the 'func' function with no arguemnts, and the nested function | |||||
# is returned. That returned function is then called with 10 as a parameter. | |||||
func() 10 | func() 10 | ||||
# Since the nested function modified it, 'str' should now be the number 10 | |||||
print str | print str | ||||
func := { | func := { | ||||
# Variables don't have to be global; this function returns a function which | |||||
# has a reference to the 'retval' variable | |||||
retval := "what's up" | retval := "what's up" | ||||
{retval} | {retval} | ||||
} | } | ||||
print func()() | print func()() | ||||
# Lastly, just print a function literal | |||||
print {0} | print {0} |
} | } | ||||
print obj.foo | print obj.foo | ||||
# Assignments | |||||
obj.foo = 100 | obj.foo = 100 | ||||
print obj.foo | print obj.foo | ||||
# Nested namespaces should work | |||||
obj.bar = {baz: "how's your day going?"} | obj.bar = {baz: "how's your day going?"} | ||||
print obj.bar.baz | print obj.bar.baz | ||||
# Empty namespace literal (should parse to namespace, not function) | |||||
print {} | print {} |