Syntax tweak: use ':' for blocks
This commit is contained in:
parent
5910998a19
commit
3c0a8f0b89
@ -5,12 +5,12 @@ language that cross-compiles to C. Tomo is designed to anticipate and influence
|
|||||||
the language design decisions of the future.
|
the language design decisions of the future.
|
||||||
|
|
||||||
```
|
```
|
||||||
func greeting(name:Text)->Text
|
func greeting(name:Text)->Text:
|
||||||
greeting := "hello {name}!"
|
greeting := "hello {name}!"
|
||||||
words := greeting:split(" ")
|
words := greeting:split(" ")
|
||||||
return " ":join([w:capitalize() for w in words])
|
return " ":join([w:capitalize() for w in words])
|
||||||
|
|
||||||
func main(name="World")
|
func main(name="World"):
|
||||||
to_say := greeting(name)
|
to_say := greeting(name)
|
||||||
say(to_say)
|
say(to_say)
|
||||||
```
|
```
|
||||||
|
66
parse.c
66
parse.c
@ -781,8 +781,10 @@ PARSER(parse_reduction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast_t *fallback = NULL;
|
ast_t *fallback = NULL;
|
||||||
if (match_word(&pos, "else"))
|
if (match_word(&pos, "else")) {
|
||||||
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
fallback = expect(ctx, pos-4, &pos, parse_expr, "I couldn't parse the expression after this 'else'");
|
fallback = expect(ctx, pos-4, &pos, parse_expr, "I couldn't parse the expression after this 'else'");
|
||||||
|
}
|
||||||
|
|
||||||
return NewAST(ctx->file, start, pos, Reduction, .iter=iter, .combination=combination, .fallback=fallback);
|
return NewAST(ctx->file, start, pos, Reduction, .iter=iter, .combination=combination, .fallback=fallback);
|
||||||
}
|
}
|
||||||
@ -838,7 +840,7 @@ PARSER(parse_if) {
|
|||||||
if (!condition) condition = expect(ctx, start, &pos, parse_expr,
|
if (!condition) condition = expect(ctx, start, &pos, parse_expr,
|
||||||
"I expected to find an expression for this 'if'");
|
"I expected to find an expression for this 'if'");
|
||||||
|
|
||||||
match_word(&pos, "then"); // optional
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
|
|
||||||
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'if' statement");
|
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'if' statement");
|
||||||
|
|
||||||
@ -848,6 +850,7 @@ PARSER(parse_if) {
|
|||||||
const char *else_start = pos;
|
const char *else_start = pos;
|
||||||
if (get_indent(ctx->file, tmp) == starting_indent && match_word(&tmp, "else")) {
|
if (get_indent(ctx->file, tmp) == starting_indent && match_word(&tmp, "else")) {
|
||||||
pos = tmp;
|
pos = tmp;
|
||||||
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
else_body = expect(ctx, else_start, &pos, parse_opt_indented_block, "I expected a body for this 'else'");
|
else_body = expect(ctx, else_start, &pos, parse_opt_indented_block, "I expected a body for this 'else'");
|
||||||
}
|
}
|
||||||
return NewAST(ctx->file, start, pos, If, .condition=condition, .body=body, .else_body=else_body);
|
return NewAST(ctx->file, start, pos, If, .condition=condition, .body=body, .else_body=else_body);
|
||||||
@ -881,7 +884,8 @@ PARSER(parse_when) {
|
|||||||
var = NULL;
|
var = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
match_word(&pos, "then"); // optional
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
|
|
||||||
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'when' clause");
|
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'when' clause");
|
||||||
clauses = new(when_clause_t, .var=var, .tag_name=tag_name, .body=body, .next=clauses);
|
clauses = new(when_clause_t, .var=var, .tag_name=tag_name, .body=body, .next=clauses);
|
||||||
tmp = pos;
|
tmp = pos;
|
||||||
@ -893,6 +897,7 @@ PARSER(parse_when) {
|
|||||||
const char *else_start = pos;
|
const char *else_start = pos;
|
||||||
if (get_indent(ctx->file, tmp) == starting_indent && match_word(&tmp, "else")) {
|
if (get_indent(ctx->file, tmp) == starting_indent && match_word(&tmp, "else")) {
|
||||||
pos = tmp;
|
pos = tmp;
|
||||||
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
else_body = expect(ctx, else_start, &pos, parse_opt_indented_block, "I expected a body for this 'else'");
|
else_body = expect(ctx, else_start, &pos, parse_opt_indented_block, "I expected a body for this 'else'");
|
||||||
}
|
}
|
||||||
return NewAST(ctx->file, start, pos, When, .subject=subject, .clauses=clauses, .else_body=else_body);
|
return NewAST(ctx->file, start, pos, When, .subject=subject, .clauses=clauses, .else_body=else_body);
|
||||||
@ -911,6 +916,7 @@ PARSER(parse_for) {
|
|||||||
}
|
}
|
||||||
expect_str(ctx, start, &pos, "in", "I expected an 'in' for this 'for'");
|
expect_str(ctx, start, &pos, "in", "I expected an 'in' for this 'for'");
|
||||||
ast_t *iter = expect(ctx, start, &pos, parse_expr, "I expected an iterable value for this 'for'");
|
ast_t *iter = expect(ctx, start, &pos, parse_expr, "I expected an iterable value for this 'for'");
|
||||||
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
match(&pos, "do"); // optional
|
match(&pos, "do"); // optional
|
||||||
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'for'");
|
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'for'");
|
||||||
|
|
||||||
@ -919,6 +925,7 @@ PARSER(parse_for) {
|
|||||||
ast_t *empty = NULL;
|
ast_t *empty = NULL;
|
||||||
if (match_word(&else_start, "else") && get_indent(ctx->file, else_start) == starting_indent) {
|
if (match_word(&else_start, "else") && get_indent(ctx->file, else_start) == starting_indent) {
|
||||||
pos = else_start;
|
pos = else_start;
|
||||||
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
empty = expect(ctx, pos, &pos, parse_opt_indented_block, "I expected a body for this 'else'");
|
empty = expect(ctx, pos, &pos, parse_opt_indented_block, "I expected a body for this 'else'");
|
||||||
}
|
}
|
||||||
return NewAST(ctx->file, start, pos, For, .index=value ? index : NULL, .value=value ? value : index, .iter=iter, .body=body, .empty=empty);
|
return NewAST(ctx->file, start, pos, For, .index=value ? index : NULL, .value=value ? value : index, .iter=iter, .body=body, .empty=empty);
|
||||||
@ -929,7 +936,7 @@ PARSER(parse_while) {
|
|||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
if (!match_word(&pos, "while")) return NULL;
|
if (!match_word(&pos, "while")) return NULL;
|
||||||
ast_t *condition = expect(ctx, start, &pos, parse_expr, "I don't see a viable condition for this 'while'");
|
ast_t *condition = expect(ctx, start, &pos, parse_expr, "I don't see a viable condition for this 'while'");
|
||||||
match(&pos, "do"); // optional
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'while'");
|
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'while'");
|
||||||
const char *tmp = pos;
|
const char *tmp = pos;
|
||||||
whitespace(&tmp);
|
whitespace(&tmp);
|
||||||
@ -1603,7 +1610,7 @@ PARSER(parse_file_body) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PARSER(parse_struct_def) {
|
PARSER(parse_struct_def) {
|
||||||
// struct Foo(...) \n body
|
// struct Foo(...) [: \n body]
|
||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
if (!match_word(&pos, "struct")) return NULL;
|
if (!match_word(&pos, "struct")) return NULL;
|
||||||
|
|
||||||
@ -1636,13 +1643,15 @@ PARSER(parse_struct_def) {
|
|||||||
|
|
||||||
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this struct");
|
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this struct");
|
||||||
|
|
||||||
const char *ns_pos = pos;
|
|
||||||
whitespace(&ns_pos);
|
|
||||||
int64_t ns_indent = get_indent(ctx->file, ns_pos);
|
|
||||||
ast_t *namespace = NULL;
|
ast_t *namespace = NULL;
|
||||||
if (ns_indent > starting_indent) {
|
if (match(&pos, ":")) {
|
||||||
pos = ns_pos;
|
const char *ns_pos = pos;
|
||||||
namespace = optional(ctx, &pos, parse_namespace);
|
whitespace(&ns_pos);
|
||||||
|
int64_t ns_indent = get_indent(ctx->file, ns_pos);
|
||||||
|
if (ns_indent > starting_indent) {
|
||||||
|
pos = ns_pos;
|
||||||
|
namespace = optional(ctx, &pos, parse_namespace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!namespace)
|
if (!namespace)
|
||||||
namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
|
namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
|
||||||
@ -1650,7 +1659,7 @@ PARSER(parse_struct_def) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast_t *parse_enum_def(parse_ctx_t *ctx, const char *pos) {
|
ast_t *parse_enum_def(parse_ctx_t *ctx, const char *pos) {
|
||||||
// tagged union: enum Foo[a, b(x:Int,y:Int)=5, ...] \n namespace
|
// tagged union: enum Foo(a, b(x:Int,y:Int)=5, ...) [: \n namespace]
|
||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
if (!match_word(&pos, "enum")) return NULL;
|
if (!match_word(&pos, "enum")) return NULL;
|
||||||
int64_t starting_indent = get_indent(ctx->file, pos);
|
int64_t starting_indent = get_indent(ctx->file, pos);
|
||||||
@ -1713,13 +1722,15 @@ ast_t *parse_enum_def(parse_ctx_t *ctx, const char *pos) {
|
|||||||
|
|
||||||
REVERSE_LIST(tags);
|
REVERSE_LIST(tags);
|
||||||
|
|
||||||
const char *ns_pos = pos;
|
|
||||||
whitespace(&ns_pos);
|
|
||||||
int64_t ns_indent = get_indent(ctx->file, ns_pos);
|
|
||||||
ast_t *namespace = NULL;
|
ast_t *namespace = NULL;
|
||||||
if (ns_indent > starting_indent) {
|
if (match(&pos, ":")) {
|
||||||
pos = ns_pos;
|
const char *ns_pos = pos;
|
||||||
namespace = optional(ctx, &pos, parse_namespace);
|
whitespace(&ns_pos);
|
||||||
|
int64_t ns_indent = get_indent(ctx->file, ns_pos);
|
||||||
|
if (ns_indent > starting_indent) {
|
||||||
|
pos = ns_pos;
|
||||||
|
namespace = optional(ctx, &pos, parse_namespace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!namespace)
|
if (!namespace)
|
||||||
namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
|
namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
|
||||||
@ -1729,7 +1740,7 @@ ast_t *parse_enum_def(parse_ctx_t *ctx, const char *pos) {
|
|||||||
|
|
||||||
PARSER(parse_lang_def) {
|
PARSER(parse_lang_def) {
|
||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
// lang Name [namespace...]
|
// lang Name: [namespace...]
|
||||||
if (!match_word(&pos, "lang")) return NULL;
|
if (!match_word(&pos, "lang")) return NULL;
|
||||||
int64_t starting_indent = get_indent(ctx->file, pos);
|
int64_t starting_indent = get_indent(ctx->file, pos);
|
||||||
spaces(&pos);
|
spaces(&pos);
|
||||||
@ -1738,13 +1749,15 @@ PARSER(parse_lang_def) {
|
|||||||
parser_err(ctx, start, pos, "I expected a name for this lang");
|
parser_err(ctx, start, pos, "I expected a name for this lang");
|
||||||
spaces(&pos);
|
spaces(&pos);
|
||||||
|
|
||||||
const char *ns_pos = pos;
|
|
||||||
whitespace(&ns_pos);
|
|
||||||
int64_t ns_indent = get_indent(ctx->file, ns_pos);
|
|
||||||
ast_t *namespace = NULL;
|
ast_t *namespace = NULL;
|
||||||
if (ns_indent > starting_indent) {
|
if (match(&pos, ":")) {
|
||||||
pos = ns_pos;
|
const char *ns_pos = pos;
|
||||||
namespace = optional(ctx, &pos, parse_namespace);
|
whitespace(&ns_pos);
|
||||||
|
int64_t ns_indent = get_indent(ctx->file, ns_pos);
|
||||||
|
if (ns_indent > starting_indent) {
|
||||||
|
pos = ns_pos;
|
||||||
|
namespace = optional(ctx, &pos, parse_namespace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!namespace)
|
if (!namespace)
|
||||||
namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
|
namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
|
||||||
@ -1843,9 +1856,10 @@ PARSER(parse_func_def) {
|
|||||||
|
|
||||||
type_ast_t *ret_type = NULL;
|
type_ast_t *ret_type = NULL;
|
||||||
spaces(&pos);
|
spaces(&pos);
|
||||||
if (match(&pos, "->") || match(&pos, ":"))
|
if (match(&pos, "->"))
|
||||||
ret_type = optional(ctx, &pos, parse_type);
|
ret_type = optional(ctx, &pos, parse_type);
|
||||||
|
|
||||||
|
expect_str(ctx, start, &pos, ":", "I expected a ':' here");
|
||||||
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block,
|
ast_t *body = expect(ctx, start, &pos, parse_opt_indented_block,
|
||||||
"This function needs a body block");
|
"This function needs a body block");
|
||||||
return NewAST(ctx->file, start, pos, FunctionDef,
|
return NewAST(ctx->file, start, pos, FunctionDef,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
func main()
|
func main():
|
||||||
if yes
|
if yes:
|
||||||
>> [:Num32]
|
>> [:Num32]
|
||||||
= [] : [Num32]
|
= [] : [Num32]
|
||||||
|
|
||||||
if yes
|
if yes:
|
||||||
>> arr := [10, 20, 30]
|
>> arr := [10, 20, 30]
|
||||||
= [10, 20, 30]
|
= [10, 20, 30]
|
||||||
|
|
||||||
@ -16,18 +16,18 @@ func main()
|
|||||||
= 3
|
= 3
|
||||||
|
|
||||||
sum := 0
|
sum := 0
|
||||||
for x in arr
|
for x in arr:
|
||||||
sum += x
|
sum += x
|
||||||
>> sum
|
>> sum
|
||||||
= 60
|
= 60
|
||||||
|
|
||||||
str := ""
|
str := ""
|
||||||
for i,x in arr
|
for i,x in arr:
|
||||||
str ++= "({i},{x})"
|
str ++= "({i},{x})"
|
||||||
>> str
|
>> str
|
||||||
= "(1,10)(2,20)(3,30)"
|
= "(1,10)(2,20)(3,30)"
|
||||||
|
|
||||||
if yes
|
if yes:
|
||||||
>> arr := [10, 20] ++ [30, 40]
|
>> arr := [10, 20] ++ [30, 40]
|
||||||
= [10, 20, 30, 40]
|
= [10, 20, 30, 40]
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ func main()
|
|||||||
>> arr
|
>> arr
|
||||||
= [10, 20, 30, 40, 50, 60, 70]
|
= [10, 20, 30, 40, 50, 60, 70]
|
||||||
|
|
||||||
if yes
|
if yes:
|
||||||
>> arr := [10, 20]
|
>> arr := [10, 20]
|
||||||
>> copy := arr
|
>> copy := arr
|
||||||
>> arr ++= 30
|
>> arr ++= 30
|
||||||
@ -48,7 +48,7 @@ func main()
|
|||||||
>> copy
|
>> copy
|
||||||
= [10, 20]
|
= [10, 20]
|
||||||
|
|
||||||
if yes
|
if yes:
|
||||||
>> [10*i for i in 5]
|
>> [10*i for i in 5]
|
||||||
= [10, 20, 30, 40, 50]
|
= [10, 20, 30, 40, 50]
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ func main()
|
|||||||
>> [x for x in y if x > 1 for y in [3, 4, 5] if y < 5]
|
>> [x for x in y if x > 1 for y in [3, 4, 5] if y < 5]
|
||||||
= [2, 3, 2, 3, 4]
|
= [2, 3, 2, 3, 4]
|
||||||
|
|
||||||
if yes
|
if yes:
|
||||||
>> arr := @[10, 20]
|
>> arr := @[10, 20]
|
||||||
>> copy := arr[]
|
>> copy := arr[]
|
||||||
>> arr:insert(30)
|
>> arr:insert(30)
|
||||||
@ -70,12 +70,12 @@ func main()
|
|||||||
>> copy
|
>> copy
|
||||||
= [10, 20]
|
= [10, 20]
|
||||||
|
|
||||||
if yes
|
if yes:
|
||||||
>> arr := [10, 20, 30]
|
>> arr := [10, 20, 30]
|
||||||
>> arr:reversed()
|
>> arr:reversed()
|
||||||
= [30, 20, 10]
|
= [30, 20, 10]
|
||||||
|
|
||||||
if yes
|
if yes:
|
||||||
>> nums := [10, -20, 30]
|
>> nums := [10, -20, 30]
|
||||||
// Sorted function doesn't mutate original:
|
// Sorted function doesn't mutate original:
|
||||||
>> nums:sorted()
|
>> nums:sorted()
|
||||||
@ -96,20 +96,20 @@ func main()
|
|||||||
|
|
||||||
>> ["A", "B", "C"]:sample(10, [1.0, 0.5, 0.0])
|
>> ["A", "B", "C"]:sample(10, [1.0, 0.5, 0.0])
|
||||||
|
|
||||||
if yes
|
if yes:
|
||||||
>> heap := [Int.random(max=50) for _ in 10]
|
>> heap := [Int.random(max=50) for _ in 10]
|
||||||
>> heap:heapify()
|
>> heap:heapify()
|
||||||
>> heap
|
>> heap
|
||||||
sorted := [:Int]
|
sorted := [:Int]
|
||||||
while #heap > 0
|
while #heap > 0:
|
||||||
sorted:insert(heap:heap_pop())
|
sorted:insert(heap:heap_pop())
|
||||||
>> sorted == sorted:sorted()
|
>> sorted == sorted:sorted()
|
||||||
= yes
|
= yes
|
||||||
for _ in 10
|
for _ in 10:
|
||||||
heap:heap_push(Int.random(max=50))
|
heap:heap_push(Int.random(max=50))
|
||||||
>> heap
|
>> heap
|
||||||
sorted = [:Int]
|
sorted = [:Int]
|
||||||
while #heap > 0
|
while #heap > 0:
|
||||||
sorted:insert(heap:heap_pop())
|
sorted:insert(heap:heap_pop())
|
||||||
>> sorted == sorted:sorted()
|
>> sorted == sorted:sorted()
|
||||||
= yes
|
= yes
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
func ping(x:Int)->[Text]
|
func ping(x:Int)->[Text]:
|
||||||
if x > 0
|
if x > 0:
|
||||||
return ["ping: {x}"] ++ pong(x-1)
|
return ["ping: {x}"] ++ pong(x-1)
|
||||||
else
|
else:
|
||||||
return ["ping: {x}"]
|
return ["ping: {x}"]
|
||||||
|
|
||||||
func pong(x:Int)->[Text]
|
func pong(x:Int)->[Text]:
|
||||||
if x > 0
|
if x > 0:
|
||||||
return ["pong: {x}"] ++ ping(x-1)
|
return ["pong: {x}"] ++ ping(x-1)
|
||||||
else
|
else:
|
||||||
return ["pong: {x}"]
|
return ["pong: {x}"]
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> ping(3)
|
>> ping(3)
|
||||||
= ["ping: 3", "pong: 2", "ping: 1", "pong: 0"]
|
= ["ping: 3", "pong: 2", "ping: 1", "pong: 0"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
enum Foo(Zero, One(x:Int), Two(x,y:Int))
|
enum Foo(Zero, One(x:Int), Two(x,y:Int))
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> Foo.Zero
|
>> Foo.Zero
|
||||||
= Foo.Zero
|
= Foo.Zero
|
||||||
>> Foo.One(123)
|
>> Foo.One(123)
|
||||||
@ -27,9 +27,9 @@ func main()
|
|||||||
>> t[Foo.Zero]
|
>> t[Foo.Zero]
|
||||||
= "missing"
|
= "missing"
|
||||||
|
|
||||||
when x is o:One
|
when x is o:One:
|
||||||
>> o.x
|
>> o.x
|
||||||
= 123
|
= 123
|
||||||
else
|
else:
|
||||||
fail("Oops")
|
fail("Oops")
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
extern CORD_cat:func(a:Text, b:Text)->Text
|
extern CORD_cat:func(a:Text, b:Text)->Text
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> CORD_cat("hello ", "world")
|
>> CORD_cat("hello ", "world")
|
||||||
= "hello world"
|
= "hello world"
|
||||||
|
26
test/for.tm
26
test/for.tm
@ -1,35 +1,35 @@
|
|||||||
|
|
||||||
func all_nums(nums:[Int])->Text
|
func all_nums(nums:[Int])->Text:
|
||||||
result := ""
|
result := ""
|
||||||
for num in nums
|
for num in nums:
|
||||||
result ++= "{num},"
|
result ++= "{num},"
|
||||||
else
|
else:
|
||||||
return "EMPTY"
|
return "EMPTY"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
func labeled_nums(nums:[Int])->Text
|
func labeled_nums(nums:[Int])->Text:
|
||||||
result := ""
|
result := ""
|
||||||
for i,num in nums
|
for i,num in nums:
|
||||||
result ++= "{i}:{num},"
|
result ++= "{i}:{num},"
|
||||||
else
|
else:
|
||||||
return "EMPTY"
|
return "EMPTY"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
func table_str(t:{Text:Text})->Text
|
func table_str(t:{Text:Text})->Text:
|
||||||
str := ""
|
str := ""
|
||||||
for k,v in t
|
for k,v in t:
|
||||||
str ++= "{k}:{v},"
|
str ++= "{k}:{v},"
|
||||||
else return "EMPTY"
|
else: return "EMPTY"
|
||||||
return str
|
return str
|
||||||
|
|
||||||
func table_key_str(t:{Text:Text})->Text
|
func table_key_str(t:{Text:Text})->Text:
|
||||||
str := ""
|
str := ""
|
||||||
for k in t
|
for k in t:
|
||||||
str ++= "{k},"
|
str ++= "{k},"
|
||||||
else return "EMPTY"
|
else: return "EMPTY"
|
||||||
return str
|
return str
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> all_nums([10,20,30])
|
>> all_nums([10,20,30])
|
||||||
= "10,20,30,"
|
= "10,20,30,"
|
||||||
>> all_nums([:Int])
|
>> all_nums([:Int])
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
func add(x:Int, y:Int)->Int
|
func add(x:Int, y:Int)->Int:
|
||||||
return x + y
|
return x + y
|
||||||
|
|
||||||
func cached_heap(x:Int; cached)->@Int
|
func cached_heap(x:Int; cached)->@Int:
|
||||||
return @x
|
return @x
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> add(3, 5)
|
>> add(3, 5)
|
||||||
= 8
|
= 8
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
func main()
|
func main():
|
||||||
>> 2 + 3
|
>> 2 + 3
|
||||||
= 5
|
= 5
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ func main()
|
|||||||
= 1
|
= 1
|
||||||
|
|
||||||
nums := ""
|
nums := ""
|
||||||
for x in 5
|
for x in 5:
|
||||||
nums ++= "{x},"
|
nums ++= "{x},"
|
||||||
>> nums
|
>> nums
|
||||||
= "1,2,3,4,5,"
|
= "1,2,3,4,5,"
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
func make_adder(x:Int)-> func(y:Int)->Int
|
func make_adder(x:Int)-> func(y:Int)->Int:
|
||||||
return func(y:Int) x + y
|
return func(y:Int) x + y
|
||||||
|
|
||||||
func suffix_fn(fn:func(t:Text)->Text, suffix:Text)->func(t:Text)->Text
|
func suffix_fn(fn:func(t:Text)->Text, suffix:Text)->func(t:Text)->Text:
|
||||||
return func(t:Text) fn(t)++suffix
|
return func(t:Text) fn(t)++suffix
|
||||||
|
|
||||||
func mul_func(n:Int, fn:func(x:Int)->Int)-> func(x:Int)->Int
|
func mul_func(n:Int, fn:func(x:Int)->Int)-> func(x:Int)->Int:
|
||||||
return func(x:Int) n*fn(x)
|
return func(x:Int) n*fn(x)
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> add_one := func(x:Int) x + 1
|
>> add_one := func(x:Int) x + 1
|
||||||
>> add_one(10)
|
>> add_one(10)
|
||||||
= 11
|
= 11
|
||||||
|
10
test/lang.tm
10
test/lang.tm
@ -1,6 +1,6 @@
|
|||||||
lang HTML
|
lang HTML:
|
||||||
HEADER := $HTML{}"<!DOCTYPE HTML>"
|
HEADER := $HTML{}"<!DOCTYPE HTML>"
|
||||||
func escape(t:Text)->HTML
|
func escape(t:Text)->HTML:
|
||||||
t = t:replace("&", "&")
|
t = t:replace("&", "&")
|
||||||
t = t:replace("<", "<")
|
t = t:replace("<", "<")
|
||||||
t = t:replace(">", ">")
|
t = t:replace(">", ">")
|
||||||
@ -8,13 +8,13 @@ lang HTML
|
|||||||
t = t:replace("'", "'")
|
t = t:replace("'", "'")
|
||||||
return HTML.from_unsafe_text(t)
|
return HTML.from_unsafe_text(t)
|
||||||
|
|
||||||
func escape_int(i:Int)->HTML
|
func escape_int(i:Int)->HTML:
|
||||||
return HTML.from_unsafe_text("{i}")
|
return HTML.from_unsafe_text("{i}")
|
||||||
|
|
||||||
func paragraph(content:HTML)->HTML
|
func paragraph(content:HTML)->HTML:
|
||||||
return $HTML{}"<p>{content}</p>"
|
return $HTML{}"<p>{content}</p>"
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> HTML.HEADER
|
>> HTML.HEADER
|
||||||
= $HTML"<!DOCTYPE HTML>"
|
= $HTML"<!DOCTYPE HTML>"
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
struct Foo(x:Int, y:Int)
|
struct Foo(x:Int, y:Int):
|
||||||
func len(f:Foo)->Num
|
func len(f:Foo)->Num:
|
||||||
return Num.sqrt(f.x*f.x + f.y*f.y)
|
return Num.sqrt(f.x*f.x + f.y*f.y)
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> 3 _min_ 5
|
>> 3 _min_ 5
|
||||||
= 3
|
= 3
|
||||||
>> 5 _min_ 3
|
>> 5 _min_ 3
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
func main()
|
func main():
|
||||||
>> n := 1.5
|
>> n := 1.5
|
||||||
= 1.5
|
= 1.5
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
struct Foo(x,y:Int)
|
struct Foo(x,y:Int)
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> (+) [10, 20, 30]
|
>> (+) [10, 20, 30]
|
||||||
= 60
|
= 60
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ struct Mixed(x:Int, text:Text)
|
|||||||
struct LinkedList(x:Int, next=!LinkedList)
|
struct LinkedList(x:Int, next=!LinkedList)
|
||||||
struct Password(text:Text; secret)
|
struct Password(text:Text; secret)
|
||||||
|
|
||||||
func test_literals()
|
func test_literals():
|
||||||
>> x := Pair(10, 20)
|
>> x := Pair(10, 20)
|
||||||
= Pair(x=10, y=20)
|
= Pair(x=10, y=20)
|
||||||
>> y := Pair(y=20, 10)
|
>> y := Pair(y=20, 10)
|
||||||
@ -14,7 +14,7 @@ func test_literals()
|
|||||||
>> x == Pair(-1, -2)
|
>> x == Pair(-1, -2)
|
||||||
= no
|
= no
|
||||||
|
|
||||||
func test_metamethods()
|
func test_metamethods():
|
||||||
>> x := Pair(10, 20)
|
>> x := Pair(10, 20)
|
||||||
>> y := Pair(100, 200)
|
>> y := Pair(100, 200)
|
||||||
>> x == y
|
>> x == y
|
||||||
@ -32,7 +32,7 @@ func test_metamethods()
|
|||||||
>> t2[y]
|
>> t2[y]
|
||||||
= "missing"
|
= "missing"
|
||||||
|
|
||||||
func test_mixed()
|
func test_mixed():
|
||||||
>> x := Mixed(10, "Hello")
|
>> x := Mixed(10, "Hello")
|
||||||
>> y := Mixed(99, "Hello")
|
>> y := Mixed(99, "Hello")
|
||||||
>> x == y
|
>> x == y
|
||||||
@ -49,7 +49,7 @@ func test_mixed()
|
|||||||
>> t[y]
|
>> t[y]
|
||||||
= "missing"
|
= "missing"
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
test_literals()
|
test_literals()
|
||||||
test_metamethods()
|
test_metamethods()
|
||||||
test_mixed()
|
test_mixed()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
func main()
|
func main():
|
||||||
>> t := {"one":1, "two":2; default=999}
|
>> t := {"one":1, "two":2; default=999}
|
||||||
= {"one":1, "two":2; default=999}
|
= {"one":1, "two":2; default=999}
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ func main()
|
|||||||
= 999
|
= 999
|
||||||
|
|
||||||
t_str := ""
|
t_str := ""
|
||||||
for k,v in t
|
for k,v in t:
|
||||||
t_str ++= "({k}:{v})"
|
t_str ++= "({k}:{v})"
|
||||||
>> t_str
|
>> t_str
|
||||||
= "(one:1)(two:2)"
|
= "(one:1)(two:2)"
|
||||||
@ -45,7 +45,7 @@ func main()
|
|||||||
= ?%{"one":1, "two":2; default=999}
|
= ?%{"one":1, "two":2; default=999}
|
||||||
|
|
||||||
t2_str := ""
|
t2_str := ""
|
||||||
for k,v in t2
|
for k,v in t2:
|
||||||
t2_str ++= "({k}:{v})"
|
t2_str ++= "({k}:{v})"
|
||||||
>> t2_str
|
>> t2_str
|
||||||
= "(three:3)"
|
= "(three:3)"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
func main()
|
func main():
|
||||||
>> str := "Hello Amélie!"
|
>> str := "Hello Amélie!"
|
||||||
>> str:upper()
|
>> str:upper()
|
||||||
= "HELLO AMÉLIE!"
|
= "HELLO AMÉLIE!"
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
imported := use ./use_import
|
imported := use ./use_import
|
||||||
|
|
||||||
func asdf()->imported.ImportedType
|
func asdf()->imported.ImportedType:
|
||||||
return imported.get_value()
|
return imported.get_value()
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
>> [:imported.ImportedType]
|
>> [:imported.ImportedType]
|
||||||
>> asdf()
|
>> asdf()
|
||||||
= ImportedType(name="Hello")
|
= ImportedType(name="Hello")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
struct ImportedType(name:Text)
|
struct ImportedType(name:Text)
|
||||||
|
|
||||||
func get_value()->ImportedType
|
func get_value()->ImportedType:
|
||||||
return ImportedType("Hello")
|
return ImportedType("Hello")
|
||||||
|
|
||||||
func main()
|
func main():
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user