Change function syntax from func(args)->ret to func(args -> ret)

This commit is contained in:
Bruce Hill 2024-10-09 13:26:28 -04:00
parent 47fca94606
commit 074cf22ad4
50 changed files with 555 additions and 532 deletions

View File

@ -5,7 +5,7 @@ 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, add_exclamation:Bool)->Text: func greeting(name:Text, add_exclamation:Bool -> Text):
message := "hello $name" message := "hello $name"
message = " ":join([w:title() for w in message:split($/{space}/)]) message = " ":join([w:title() for w in message:split($/{space}/)])
if add_exclamation: if add_exclamation:

3
ast.c
View File

@ -130,7 +130,8 @@ CORD ast_to_xml(ast_t *ast)
optional_tagged("filter", data.filter)) optional_tagged("filter", data.filter))
T(FunctionDef, "<FunctionDef name=\"%r\">%r%r<body>%r</body></FunctionDef>", ast_to_xml(data.name), T(FunctionDef, "<FunctionDef name=\"%r\">%r%r<body>%r</body></FunctionDef>", ast_to_xml(data.name),
arg_list_to_xml(data.args), optional_tagged_type("return-type", data.ret_type), ast_to_xml(data.body)) arg_list_to_xml(data.args), optional_tagged_type("return-type", data.ret_type), ast_to_xml(data.body))
T(Lambda, "<Lambda>%r<body>%r</body></Lambda>)", arg_list_to_xml(data.args), ast_to_xml(data.body)) T(Lambda, "<Lambda>%r%r<body>%r</body></Lambda>)", arg_list_to_xml(data.args),
optional_tagged_type("return-type", data.ret_type), ast_to_xml(data.body))
T(FunctionCall, "<FunctionCall><function>%r</function>%r</FunctionCall>", ast_to_xml(data.fn), arg_list_to_xml(data.args)) T(FunctionCall, "<FunctionCall><function>%r</function>%r</FunctionCall>", ast_to_xml(data.fn), arg_list_to_xml(data.args))
T(MethodCall, "<MethodCall><self>%r</self><method>%s</method>%r</MethodCall>", ast_to_xml(data.self), data.name, arg_list_to_xml(data.args)) T(MethodCall, "<MethodCall><self>%r</self><method>%s</method>%r</MethodCall>", ast_to_xml(data.self), data.name, arg_list_to_xml(data.args))
T(Block, "<Block>%r</Block>", ast_list_to_xml(data.statements)) T(Block, "<Block>%r</Block>", ast_list_to_xml(data.statements))

1
ast.h
View File

@ -233,6 +233,7 @@ struct ast_s {
} FunctionDef; } FunctionDef;
struct { struct {
arg_ast_t *args; arg_ast_t *args;
type_ast_t *ret_type;
ast_t *body; ast_t *body;
int64_t id; int64_t id;
} Lambda; } Lambda;

View File

@ -2519,6 +2519,16 @@ CORD compile(env_t *env, ast_t *ast)
type_t *ret_t = get_type(body_scope, lambda->body); type_t *ret_t = get_type(body_scope, lambda->body);
if (ret_t->tag == ReturnType) if (ret_t->tag == ReturnType)
ret_t = Match(ret_t, ReturnType)->ret; ret_t = Match(ret_t, ReturnType)->ret;
if (lambda->ret_type) {
type_t *declared = parse_type_ast(env, lambda->ret_type);
if (can_promote(ret_t, declared))
ret_t = declared;
else
code_err(ast, "This function was declared to return a value of type %T, but actually returns a value of type %T",
declared, ret_t);
}
fn_ctx.return_type = ret_t; fn_ctx.return_type = ret_t;
if (env->fn_ctx->closed_vars) { if (env->fn_ctx->closed_vars) {

View File

@ -44,7 +44,7 @@ Gets a line of user input text with a prompt.
**Usage:** **Usage:**
```markdown ```markdown
ask(prompt:Text, bold:Bool = yes, force_tty:Bool = yes) -> Void ask(prompt:Text, bold:Bool = yes, force_tty:Bool = yes -> Void)
``` ```
**Parameters:** **Parameters:**
@ -79,7 +79,7 @@ Exits the program with a given status and optionally prints a message.
**Usage:** **Usage:**
```markdown ```markdown
ask(message:Text? = !Text, status:Int32 = 1[32]) -> Void ask(message:Text? = !Text, status:Int32 = 1[32] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -106,7 +106,7 @@ Prints a message to the console.
**Usage:** **Usage:**
```markdown ```markdown
say(text:Text, newline:Bool = yes) -> Void say(text:Text, newline:Bool = yes -> Void)
``` ```
**Parameters:** **Parameters:**
@ -132,7 +132,7 @@ Pause execution for a given number of seconds.
**Usage:** **Usage:**
```markdown ```markdown
sleep(seconds: Num) -> Void sleep(seconds: Num -> Void)
``` ```
**Parameters:** **Parameters:**
@ -156,7 +156,7 @@ Prints a message to the console, aborts the program, and prints a stack trace.
**Usage:** **Usage:**
```markdown ```markdown
fail(message:Text) -> Abort fail(message:Text -> Abort)
``` ```
**Parameters:** **Parameters:**
@ -180,7 +180,7 @@ Gets the current time. This is an alias for `DateTime.now()`.
**Usage:** **Usage:**
```markdown ```markdown
now() -> DateTime now(->DateTime)
``` ```
**Parameters:** **Parameters:**

View File

@ -239,7 +239,7 @@ Performs a binary search on a sorted array.
**Usage:** **Usage:**
```markdown ```markdown
binary_search(arr: [T], by=T.compare) -> Int binary_search(arr: [T], by=T.compare -> Int)
``` ```
**Parameters:** **Parameters:**
@ -275,7 +275,7 @@ Creates a new array with elements spaced by the specified step value.
**Usage:** **Usage:**
```markdown ```markdown
by(arr: [T], step: Int) -> [T] by(arr: [T], step: Int -> [T])
``` ```
**Parameters:** **Parameters:**
@ -301,7 +301,7 @@ Clears all elements from the array.
**Usage:** **Usage:**
```markdown ```markdown
clear(arr: & [T]) -> Void clear(arr: & [T] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -325,7 +325,7 @@ Counts the occurrences of each element in the array.
**Usage:** **Usage:**
```markdown ```markdown
counts(arr: [T]) -> {T: Int} counts(arr: [T] -> {T: Int})
``` ```
**Parameters:** **Parameters:**
@ -350,7 +350,7 @@ Finds the index of the first occurrence of an element (if any).
**Usage:** **Usage:**
```markdown ```markdown
find(arr: [T]) -> Int? find(arr: [T] -> Int?)
``` ```
**Parameters:** **Parameters:**
@ -378,7 +378,7 @@ Find the index of the first item that matches a predicate function (if any).
**Usage:** **Usage:**
```markdown ```markdown
first(arr: [T], predicate: func(item:&T)->Bool) -> Int first(arr: [T], predicate: func(item:&T)->Bool -> Int)
``` ```
**Parameters:** **Parameters:**
@ -408,7 +408,7 @@ Returns a slice of the array starting from a specified index.
**Usage:** **Usage:**
```markdown ```markdown
from(arr: [T], first: Int) -> [T] from(arr: [T], first: Int -> [T])
``` ```
**Parameters:** **Parameters:**
@ -434,7 +434,7 @@ Checks if the array has any elements.
**Usage:** **Usage:**
```markdown ```markdown
has(arr: [T]) -> Bool has(arr: [T] -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -460,7 +460,7 @@ Removes and returns the top element of a heap. By default, this is the
**Usage:** **Usage:**
```markdown ```markdown
heap_pop(arr: & [T], by=T.compare) -> T heap_pop(arr: & [T], by=T.compare -> T)
``` ```
**Parameters:** **Parameters:**
@ -490,7 +490,7 @@ is a *minimum* heap.
**Usage:** **Usage:**
```markdown ```markdown
heap_push(arr: & [T], item: T, by=T.compare) -> Void heap_push(arr: & [T], item: T, by=T.compare -> Void)
``` ```
**Parameters:** **Parameters:**
@ -517,7 +517,7 @@ Converts an array into a heap.
**Usage:** **Usage:**
```markdown ```markdown
heapify(arr: & [T], by=T.compare) -> Void heapify(arr: & [T], by=T.compare -> Void)
``` ```
**Parameters:** **Parameters:**
@ -544,7 +544,7 @@ Inserts an element at a specified position in the array.
**Usage:** **Usage:**
```markdown ```markdown
insert(arr: & [T], item: T, at: Int = 0) -> Void insert(arr: & [T], item: T, at: Int = 0 -> Void)
``` ```
**Parameters:** **Parameters:**
@ -579,7 +579,7 @@ Inserts an array of items at a specified position in the array.
**Usage:** **Usage:**
```markdown ```markdown
insert_all(arr: & [T], items: [T], at: Int = 0) -> Void insert_all(arr: & [T], items: [T], at: Int = 0 -> Void)
``` ```
**Parameters:** **Parameters:**
@ -614,7 +614,7 @@ Selects a random element from the array.
**Usage:** **Usage:**
```markdown ```markdown
random(arr: [T]) -> T random(arr: [T] -> T)
``` ```
**Parameters:** **Parameters:**
@ -639,7 +639,7 @@ Removes elements from the array starting at a specified index.
**Usage:** **Usage:**
```markdown ```markdown
remove_at(arr: & [T], at: Int = -1, count: Int = 1) -> Void remove_at(arr: & [T], at: Int = -1, count: Int = 1 -> Void)
``` ```
**Parameters:** **Parameters:**
@ -672,7 +672,7 @@ Removes all occurrences of a specified item from the array.
**Usage:** **Usage:**
```markdown ```markdown
remove_item(arr: & [T], item: T, max_count: Int = -1) -> Void remove_item(arr: & [T], item: T, max_count: Int = -1 -> Void)
``` ```
**Parameters:** **Parameters:**
@ -705,7 +705,7 @@ Returns a reversed slice of the array.
**Usage:** **Usage:**
```markdown ```markdown
reversed(arr: [T]) -> [T] reversed(arr: [T] -> [T])
``` ```
**Parameters:** **Parameters:**
@ -731,7 +731,7 @@ probabilities.
**Usage:** **Usage:**
```markdown ```markdown
sample(arr: [T], count: Int, weights: [Num]? = ![Num]) -> [T] sample(arr: [T], count: Int, weights: [Num]? = ![Num] -> [T])
``` ```
**Parameters:** **Parameters:**
@ -769,7 +769,7 @@ Shuffles the elements of the array in place.
**Usage:** **Usage:**
```markdown ```markdown
shuffle(arr: & [T]) -> Void shuffle(arr: & [T] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -793,7 +793,7 @@ Creates a new array with elements shuffled.
**Usage:** **Usage:**
```markdown ```markdown
shuffled(arr: [T]) -> [T] shuffled(arr: [T] -> [T])
``` ```
**Parameters:** **Parameters:**
@ -818,7 +818,7 @@ Sorts the elements of the array in place in ascending order (small to large).
**Usage:** **Usage:**
```markdown ```markdown
sort(arr: & [T], by=T.compare) -> Void sort(arr: & [T], by=T.compare -> Void)
``` ```
**Parameters:** **Parameters:**
@ -851,7 +851,7 @@ Creates a new array with elements sorted.
**Usage:** **Usage:**
```markdown ```markdown
sorted(arr: [T], by=T.compare) -> [T] sorted(arr: [T], by=T.compare -> [T])
``` ```
**Parameters:** **Parameters:**
@ -881,7 +881,7 @@ Returns a slice of the array from the start of the original array up to a specif
**Usage:** **Usage:**
```markdown ```markdown
to(arr: [T], last: Int) -> [T] to(arr: [T], last: Int -> [T])
``` ```
**Parameters:** **Parameters:**
@ -910,7 +910,7 @@ Returns a Set that contains the unique elements of the array.
**Usage:** **Usage:**
```markdown ```markdown
unique(arr: [T]) -> {T} unique(arr: [T] -> {T})
``` ```
**Parameters:** **Parameters:**

View File

@ -16,7 +16,7 @@ boolean values are case-insensitive variations of `yes`/`no`, `y`/`n`,
**Usage:** **Usage:**
```tomo ```tomo
from_text(text: Text, success: Bool = !&Bool) -> Bool from_text(text: Text, success: Bool = !&Bool -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -49,7 +49,7 @@ Generates a random boolean value based on a specified probability.
**Usage:** **Usage:**
```tomo ```tomo
random(p: Float = 0.5) -> Bool random(p: Float = 0.5 -> Bool)
``` ```
**Parameters:** **Parameters:**

View File

@ -16,7 +16,7 @@ Generates a random byte value in the specified range.
**Usage:** **Usage:**
```tomo ```tomo
random(min: Byte = Byte.min, max: Byte = Byte.max) -> Byte random(min: Byte = Byte.min, max: Byte = Byte.max -> Byte)
``` ```
**Parameters:** **Parameters:**

View File

@ -31,7 +31,7 @@ Adds an item to the channel.
**Usage:** **Usage:**
```markdown ```markdown
give(channel:|T|, item: T, front: Bool = no) -> Void give(channel:|T|, item: T, front: Bool = no -> Void)
``` ```
**Parameters:** **Parameters:**
@ -57,7 +57,7 @@ Adds multiple items to the channel.
**Usage:** **Usage:**
```markdown ```markdown
give_all(channel:|T|, items: [T], front: Bool = no) -> Void give_all(channel:|T|, items: [T], front: Bool = no -> Void)
``` ```
**Parameters:** **Parameters:**
@ -83,7 +83,7 @@ Removes and returns an item from the channel. If the channel is empty, it waits
**Usage:** **Usage:**
```markdown ```markdown
get(channel:|T|, front: Bool = yes) -> T get(channel:|T|, front: Bool = yes -> T)
``` ```
**Parameters:** **Parameters:**
@ -110,7 +110,7 @@ it. If the channel is empty, it waits until an item is available.
**Usage:** **Usage:**
```markdown ```markdown
peek(channel:|T|, front: Bool = yes) -> T peek(channel:|T|, front: Bool = yes -> T)
``` ```
**Parameters:** **Parameters:**
@ -136,7 +136,7 @@ Removes all items from the channel.
**Usage:** **Usage:**
```markdown ```markdown
clear(channel:|T|) -> Void clear(channel:|T| -> Void)
``` ```
**Parameters:** **Parameters:**
@ -160,7 +160,7 @@ Returns a list of all items currently in the channel without removing them.
**Usage:** **Usage:**
```markdown ```markdown
channel:view() -> [T] channel:view(->[T])
``` ```
**Parameters:** **Parameters:**

View File

@ -79,7 +79,7 @@ calculated.
**Usage:** **Usage:**
```markdown ```markdown
datetime:after(seconds : Num = 0.0, minutes : Num = 0.0, hours : Num = 0.0, days : Int = 0, weeks : Int = 0, months : Int = 0, years : Int = 0, timezone : Text? = !Text) -> DateTime datetime:after(seconds : Num = 0.0, minutes : Num = 0.0, hours : Num = 0.0, days : Int = 0, weeks : Int = 0, months : Int = 0, years : Int = 0, timezone : Text? = !Text -> DateTime)
``` ```
**Parameters:** **Parameters:**
@ -113,7 +113,7 @@ specifier, which gives the date in `YYYY-MM-DD` form.
**Usage:** **Usage:**
```markdown ```markdown
datetime:date(timezone : Text? = !Text) -> Text datetime:date(timezone : Text? = !Text -> Text)
``` ```
**Parameters:** **Parameters:**
@ -141,7 +141,7 @@ timezone.
**Usage:** **Usage:**
```markdown ```markdown
datetime:format(format: Text = "%Y-%m-%dT%H:%M:%S%z", timezone : Text? = !Text) -> Text datetime:format(format: Text = "%Y-%m-%dT%H:%M:%S%z", timezone : Text? = !Text -> Text)
``` ```
**Parameters:** **Parameters:**
@ -168,7 +168,7 @@ the given UNIX epoch timestamp (seconds since January 1, 1970 UTC).
**Usage:** **Usage:**
```markdown ```markdown
DateTime.from_unix_timestamp(timestamp: Int64) -> DateTime DateTime.from_unix_timestamp(timestamp: Int64 -> DateTime)
``` ```
**Parameters:** **Parameters:**
@ -195,7 +195,7 @@ provided optional fields.
**Usage:** **Usage:**
```markdown ```markdown
datetime:get(year : &Int? = !&Int, month : &Int? = !&Int, day : &Int? = !&Int, hour : &Int? = !&Int, minute : &Int? = !&Int, second : &Int? = !&Int, nanosecond : &Int? = !&Int, weekday : &Int? = !&Int, timezone : Text? = !Text) -> Void datetime:get(year : &Int? = !&Int, month : &Int? = !&Int, day : &Int? = !&Int, hour : &Int? = !&Int, minute : &Int? = !&Int, second : &Int? = !&Int, nanosecond : &Int? = !&Int, weekday : &Int? = !&Int, timezone : Text? = !Text -> Void)
``` ```
**Parameters:** **Parameters:**
@ -233,7 +233,7 @@ calling `DateTime.set_local_timezone(...)`.
**Usage:** **Usage:**
```markdown ```markdown
DateTime.get_local_timezone() -> Text DateTime.get_local_timezone(->Text)
``` ```
**Parameters:** **Parameters:**
@ -258,7 +258,7 @@ Return the number of hours until a given datetime.
**Usage:** **Usage:**
```markdown ```markdown
datetime:hours_till(then:DateTime) -> Num datetime:hours_till(then:DateTime -> Num)
``` ```
**Parameters:** **Parameters:**
@ -284,7 +284,7 @@ Return the number of minutes until a given datetime.
**Usage:** **Usage:**
```markdown ```markdown
datetime:minutes_till(then:DateTime) -> Num datetime:minutes_till(then:DateTime -> Num)
``` ```
**Parameters:** **Parameters:**
@ -312,7 +312,7 @@ constructor.
**Usage:** **Usage:**
```markdown ```markdown
DateTime.new(year : Int, month : Int, day : Int, hour : Int = 0, minute : Int = 0, second : Num = 0.0) -> DateTime DateTime.new(year : Int, month : Int, day : Int, hour : Int = 0, minute : Int = 0, second : Num = 0.0 -> DateTime)
``` ```
**Parameters:** **Parameters:**
@ -351,7 +351,7 @@ is the same as the global function `now()`.
**Usage:** **Usage:**
```markdown ```markdown
DateTime.now() -> DateTime DateTime.now(->DateTime)
``` ```
**Parameters:** **Parameters:**
@ -377,7 +377,7 @@ or a null value if the value could not be successfully parsed.
**Usage:** **Usage:**
```markdown ```markdown
DateTime.parse(text: Text, format: Text = "%Y-%m-%dT%H:%M:%S%z") -> DateTime? DateTime.parse(text: Text, format: Text = "%Y-%m-%dT%H:%M:%S%z" -> DateTime?)
``` ```
**Parameters:** **Parameters:**
@ -410,7 +410,7 @@ between two `DateTime`s. For example: `5 minutes ago` or `1 day later`
**Usage:** **Usage:**
```markdown ```markdown
datetime:relative(relative_to : DateTime = DateTime.now(), timezone : Text? = !Text) -> Text datetime:relative(relative_to : DateTime = DateTime.now(), timezone : Text? = !Text -> Text)
``` ```
**Parameters:** **Parameters:**
@ -445,7 +445,7 @@ Return the number of seconds until a given datetime.
**Usage:** **Usage:**
```markdown ```markdown
datetime:seconds_till(then:DateTime) -> Num datetime:seconds_till(then:DateTime -> Num)
``` ```
**Parameters:** **Parameters:**
@ -475,7 +475,7 @@ converted to text.
**Usage:** **Usage:**
```markdown ```markdown
DateTime.set_local_timezone(timezone : Text? = !Text) -> Void DateTime.set_local_timezone(timezone : Text? = !Text -> Void)
``` ```
**Parameters:** **Parameters:**
@ -501,7 +501,7 @@ Return a text representation of the time component of the given datetime.
**Usage:** **Usage:**
```markdown ```markdown
datetime:time(seconds : Bool = no, am_pm : Bool = yes, timezone : Text? = !Text) -> Text datetime:time(seconds : Bool = no, am_pm : Bool = yes, timezone : Text? = !Text -> Text)
``` ```
**Parameters:** **Parameters:**
@ -537,7 +537,7 @@ January 1, 1970 UTC).
**Usage:** **Usage:**
```markdown ```markdown
datetime:unix_timestamp() -> Int64 datetime:unix_timestamp(->Int64)
``` ```
**Parameters:** **Parameters:**

View File

@ -54,7 +54,7 @@ from a function with an explicit return type:
enum ArgumentType(AnInt(x:Int), SomeText(text:Text)) enum ArgumentType(AnInt(x:Int), SomeText(text:Text))
enum ReturnType(Nothing, AnInt(x:Int)) enum ReturnType(Nothing, AnInt(x:Int))
func increment(arg:ArgumentType)->ReturnType: func increment(arg:ArgumentType -> ReturnType):
when arg is AnInt(x): when arg is AnInt(x):
return AnInt(x + 1) return AnInt(x + 1)
is SomeText: is SomeText:

View File

@ -3,7 +3,7 @@
In Tomo, you can define functions with the `func` keyword: In Tomo, you can define functions with the `func` keyword:
```tomo ```tomo
func add(x:Int, y:Int)->Int: func add(x:Int, y:Int -> Int):
return x + y return x + y
``` ```
@ -11,7 +11,7 @@ Functions require you to explicitly write out the types of each argument and
the return type of the function (unless the function doesn't return any values). the return type of the function (unless the function doesn't return any values).
For convenience, you can lump arguments with the same type together to avoid For convenience, you can lump arguments with the same type together to avoid
having to retype the same type name: `func add(x, y:Int)->Int` having to retype the same type name: `func add(x, y:Int -> Int)`
## Default Arguments ## Default Arguments
@ -19,7 +19,7 @@ Instead of giving a type, you can provide a default argument and the type
checker will infer the type of the argument from that value: checker will infer the type of the argument from that value:
```tomo ```tomo
func increment(x:Int, amount=1)->Int: func increment(x:Int, amount=1 -> Int):
return x + amount return x + amount
``` ```
@ -35,7 +35,7 @@ callsite:
``` ```
**Note:** Default arguments are re-evaluated at the callsite for each function **Note:** Default arguments are re-evaluated at the callsite for each function
call, so if your default argument is `func foo(x=Int.random(1,10))->Int`, then call, so if your default argument is `func foo(x=Int.random(1,10) -> Int)`, then
each time you call the function without an `x` argument, it will give you a new each time you call the function without an `x` argument, it will give you a new
random number. random number.
@ -68,7 +68,7 @@ Tomo supports automatic function caching using the `cached` or `cache_size=N`
attributes on a function definition: attributes on a function definition:
```tomo ```tomo
func add(x, y:Int; cached)->Int: func add(x, y:Int -> Int; cached):
return x + y return x + y
``` ```
@ -78,13 +78,13 @@ return value for those arguments. The above example is functionally similar to
the following code: the following code:
```tomo ```tomo
func _add(x, y:Int)->Int: func _add(x, y:Int -> Int):
return x + y return x + y
struct add_args(x,y:Int) struct add_args(x,y:Int)
add_cache := @{:add_args:Int} add_cache := @{:add_args:Int}
func add(x, y:Int)->Int: func add(x, y:Int -> Int):
args := add_args(x, y) args := add_args(x, y)
if add_cache:has(args): if add_cache:has(args):
return add_cache:get(args) return add_cache:get(args)
@ -98,7 +98,7 @@ evicted if the cache has reached the maximum size and needs to insert a new
entry: entry:
```tomo ```tomo
func doop(x:Int, y:Text, z:[Int]; cache_size=100)->Text: func doop(x:Int, y:Text, z:[Int]; cache_size=100 -> Text):
return "x=$x y=$y z=$z" return "x=$x y=$y z=$z"
``` ```
@ -108,7 +108,7 @@ Functions can also be given an `inline` attribute, which encourages the
compiler to inline the function when possible: compiler to inline the function when possible:
```tomo ```tomo
func add(x, y:Int; inline)->Int: func add(x, y:Int -> Int; inline):
return x + y return x + y
``` ```
@ -137,7 +137,10 @@ fn := func(x,y:Int):
Lambda functions must declare the types of their arguments, but do not require Lambda functions must declare the types of their arguments, but do not require
declaring the return type. Because lambdas cannot be recursive or corecursive declaring the return type. Because lambdas cannot be recursive or corecursive
(since they aren't declared with a name), it is always possible to infer the (since they aren't declared with a name), it is always possible to infer the
return type without much difficulty. return type without much difficulty. If you do choose to declare a return type,
the compiler will attempt to promote return values to that type, or give a
compiler error if the return value is not compatible with the declared return
type.
## Closures ## Closures
@ -148,7 +151,7 @@ values. **Captured values are copied to a new location at the moment the lambda
is created and will not reflect changes to local variables.** is created and will not reflect changes to local variables.**
```tomo ```tomo
func create_adder(n:Int) -> func(i:Int)->Int: func create_adder(n:Int -> func(i:Int -> Int)):
adder := func(i:Int): adder := func(i:Int):
return n + i return n + i

View File

@ -37,7 +37,7 @@ Formats an integer as a string with a specified number of digits.
**Usage:** **Usage:**
```tomo ```tomo
format(i: Int, digits: Int = 0) -> Text format(i: Int, digits: Int = 0 -> Text)
``` ```
**Parameters:** **Parameters:**
@ -63,7 +63,7 @@ Converts an integer to its hexadecimal representation.
**Usage:** **Usage:**
```tomo ```tomo
hex(i: Int, digits: Int = 0, uppercase: Bool = yes, prefix: Bool = yes) -> Text hex(i: Int, digits: Int = 0, uppercase: Bool = yes, prefix: Bool = yes -> Text)
``` ```
**Parameters:** **Parameters:**
@ -91,7 +91,7 @@ Converts an integer to its octal representation.
**Usage:** **Usage:**
```tomo ```tomo
octal(i: Int, digits: Int = 0, prefix: Bool = yes) -> Text octal(i: Int, digits: Int = 0, prefix: Bool = yes -> Text)
``` ```
**Parameters:** **Parameters:**
@ -118,7 +118,7 @@ Generates a random integer between the specified minimum and maximum values.
**Usage:** **Usage:**
```tomo ```tomo
random(min: Int, max: Int) -> Int random(min: Int, max: Int -> Int)
``` ```
**Parameters:** **Parameters:**
@ -144,7 +144,7 @@ Converts a text representation of an integer into an integer.
**Usage:** **Usage:**
```tomo ```tomo
from_text(text: Text, success: Bool = !&Bool?) -> Int from_text(text: Text, success: Bool = !&Bool? -> Int)
``` ```
**Parameters:** **Parameters:**
@ -188,7 +188,7 @@ Creates an inclusive range of integers between the specified start and end value
**Usage:** **Usage:**
```tomo ```tomo
to(from: Int, to: Int) -> Range to(from: Int, to: Int -> Range)
``` ```
**Parameters:** **Parameters:**
@ -214,7 +214,7 @@ Calculates the absolute value of an integer.
**Usage:** **Usage:**
```tomo ```tomo
abs(x: Int) -> Int abs(x: Int -> Int)
``` ```
**Parameters:** **Parameters:**
@ -239,7 +239,7 @@ Calculates the square root of an integer.
**Usage:** **Usage:**
```tomo ```tomo
sqrt(x: Int) -> Int sqrt(x: Int -> Int)
``` ```
**Parameters:** **Parameters:**
@ -272,7 +272,7 @@ for more details.
**Usage:** **Usage:**
```tomo ```tomo
is_prime(x: Int, reps: Int = 50) -> Bool is_prime(x: Int, reps: Int = 50 -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -306,7 +306,7 @@ for more details.
**Usage:** **Usage:**
```tomo ```tomo
next_prime(x: Int) -> Int next_prime(x: Int -> Int)
``` ```
**Parameters:** **Parameters:**
@ -339,7 +339,7 @@ for more details.
**Usage:** **Usage:**
```tomo ```tomo
prev_prime(x: Int) -> Int prev_prime(x: Int -> Int)
``` ```
**Parameters:** **Parameters:**
@ -365,7 +365,7 @@ that range.
**Usage:** **Usage:**
```tomo ```tomo
clamped(x, low, high: Int) -> Int clamped(x, low, high: Int -> Int)
``` ```
**Parameters:** **Parameters:**

View File

@ -10,7 +10,7 @@ where a different type of string is needed.
```tomo ```tomo
lang HTML: lang HTML:
func escape(t:Text)->HTML: func escape(t:Text -> HTML):
t = t:replace_all({ t = t:replace_all({
$/&/: "&amp;", $/&/: "&amp;",
$/</: "&lt;", $/</: "&lt;",
@ -20,7 +20,7 @@ lang HTML:
}) })
return HTML.without_escaping(t) return HTML.without_escaping(t)
func paragraph(content:HTML)->HTML: func paragraph(content:HTML -> HTML):
return $HTML"<p>$content</p>" return $HTML"<p>$content</p>"
``` ```
@ -74,10 +74,10 @@ instead of building a global function called `execute()` that takes a
```tomo ```tomo
lang Sh: lang Sh:
func escape(text:Text)->Sh: func escape(text:Text -> Sh):
return Sh.without_escaping("'" ++ text:replace($/'/, "''") ++ "'") return Sh.without_escaping("'" ++ text:replace($/'/, "''") ++ "'")
func execute(sh:Sh)->Text: func execute(sh:Sh -> Text):
... ...
dir := ask("List which dir? ") dir := ask("List which dir? ")

View File

@ -3,25 +3,25 @@
This language relies on a small set of "metamethods" which define special This language relies on a small set of "metamethods" which define special
behavior that is required for all types: behavior that is required for all types:
- `as_text(obj:&(optional)T, colorize=no, type:&TypeInfo_t)->Text`: a method to - `func as_text(obj:&(optional)T, colorize=no, type:&TypeInfo_t -> Text)`: a method to
convert the type to a string. If `colorize` is `yes`, then the method should convert the type to a string. If `colorize` is `yes`, then the method should
include ANSI escape codes for syntax highlighting. If the `obj` pointer is include ANSI escape codes for syntax highlighting. If the `obj` pointer is
`NULL`, a string representation of the type will be returned instead. `NULL`, a string representation of the type will be returned instead.
- `compare(x:&T, y:&T, type:&TypeInfo_t)->Int32`: Return an integer representing - `func compare(x:&T, y:&T, type:&TypeInfo_t -> Int32)`: Return an integer representing
the result of comparing `x` and `y`, where negative numbers mean `x` is less the result of comparing `x` and `y`, where negative numbers mean `x` is less
than `y`, zero means `x` is equal to `y`, and positive numbers mean `x` is than `y`, zero means `x` is equal to `y`, and positive numbers mean `x` is
greater than `y`. For the purpose of floating point numbers, `NaN` is sorted greater than `y`. For the purpose of floating point numbers, `NaN` is sorted
as greater than any other number value and `NaN` values are compared bitwise as greater than any other number value and `NaN` values are compared bitwise
between each other. between each other.
- `equals(x:&T, y:&T, type:&TypeInfo_t)->Bool`: This is the same as comparing two - `func equals(x:&T, y:&T, type:&TypeInfo_t -> Bool)`: This is the same as comparing two
numbers to check for zero, except for some minor differences: floating point numbers to check for zero, except for some minor differences: floating point
`NaN` values are _not_ equal to each other (IEEE 754) and the implementation `NaN` values are _not_ equal to each other (IEEE 754) and the implementation
of `equals` may be faster to compute than `compare` for certain types, such of `equals` may be faster to compute than `compare` for certain types, such
as tables. as tables.
- `hash(x:&T, type:&TypeInfo_t)->Int32`: Values are hashed when used as keys in a - `func hash(x:&T, type:&TypeInfo_t -> Int32)`: Values are hashed when used as keys in a
table or set. Hashing is consistent with equality, so two values that are table or set. Hashing is consistent with equality, so two values that are
equal _must_ hash to the same hash value, ideally in a way that makes it equal _must_ hash to the same hash value, ideally in a way that makes it
unlikely that two different values will have the same hash value. unlikely that two different values will have the same hash value.

View File

@ -17,7 +17,7 @@ my_var := 123
struct Baz(x:Int): struct Baz(x:Int):
member := 5 member := 5
func frob(b:Baz)->Int: func frob(b:Baz -> Int):
return b.x return b.x
``` ```

View File

@ -42,7 +42,7 @@ Calculates the absolute value of a number.
**Usage:** **Usage:**
```tomo ```tomo
abs(n: Num) -> Num abs(n: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -67,7 +67,7 @@ Computes the arc cosine of a number.
**Usage:** **Usage:**
```tomo ```tomo
acos(x: Num) -> Num acos(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -92,7 +92,7 @@ Computes the inverse hyperbolic cosine of a number.
**Usage:** **Usage:**
```tomo ```tomo
acosh(x: Num) -> Num acosh(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -117,7 +117,7 @@ Computes the arc sine of a number.
**Usage:** **Usage:**
```tomo ```tomo
asin(x: Num) -> Num asin(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -142,7 +142,7 @@ Computes the inverse hyperbolic sine of a number.
**Usage:** **Usage:**
```tomo ```tomo
asinh(x: Num) -> Num asinh(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -167,7 +167,7 @@ Computes the arc tangent of the quotient of two numbers.
**Usage:** **Usage:**
```tomo ```tomo
atan2(x: Num, y: Num) -> Num atan2(x: Num, y: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -193,7 +193,7 @@ Computes the arc tangent of a number.
**Usage:** **Usage:**
```tomo ```tomo
atan(x: Num) -> Num atan(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -218,7 +218,7 @@ Computes the inverse hyperbolic tangent of a number.
**Usage:** **Usage:**
```tomo ```tomo
atanh(x: Num) -> Num atanh(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -243,7 +243,7 @@ Computes the cube root of a number.
**Usage:** **Usage:**
```tomo ```tomo
cbrt(x: Num) -> Num cbrt(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -268,7 +268,7 @@ Rounds a number up to the nearest integer.
**Usage:** **Usage:**
```tomo ```tomo
ceil(x: Num) -> Num ceil(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -293,7 +293,7 @@ Copies the sign of one number to another.
**Usage:** **Usage:**
```tomo ```tomo
copysign(x: Num, y: Num) -> Num copysign(x: Num, y: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -319,7 +319,7 @@ Computes the cosine of a number (angle in radians).
**Usage:** **Usage:**
```tomo ```tomo
cos(x: Num) -> Num cos(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -344,7 +344,7 @@ Computes the hyperbolic cosine of a number.
**Usage:** **Usage:**
```tomo ```tomo
cosh(x: Num) -> Num cosh(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -369,7 +369,7 @@ Computes the error function of a number.
**Usage:** **Usage:**
```tomo ```tomo
erf(x: Num) -> Num erf(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -394,7 +394,7 @@ Computes the complementary error function of a number.
**Usage:** **Usage:**
```tomo ```tomo
erfc(x: Num) -> Num erfc(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -419,7 +419,7 @@ Computes \( 2^x \) for a number.
**Usage:** **Usage:**
```tomo ```tomo
exp2(x: Num) -> Num exp2(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -444,7 +444,7 @@ Computes the exponential function \( e^x \) for a number.
**Usage:** **Usage:**
```tomo ```tomo
exp(x: Num) -> Num exp(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -469,7 +469,7 @@ Computes \( e^x - 1 \) for a number.
**Usage:** **Usage:**
```tomo ```tomo
expm1(x: Num) -> Num expm1(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -494,7 +494,7 @@ Computes the positive difference between two numbers.
**Usage:** **Usage:**
```tomo ```tomo
fdim(x: Num, y: Num) -> Num fdim(x: Num, y: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -522,7 +522,7 @@ Rounds a number down to the nearest integer.
**Usage:** **Usage:**
```tomo ```tomo
floor(x: Num) -> Num floor(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -547,7 +547,7 @@ Formats a number as a string with a specified precision.
**Usage:** **Usage:**
```tomo ```tomo
format(n: Num, precision: Int = 0) -> Text format(n: Num, precision: Int = 0 -> Text)
``` ```
**Parameters:** **Parameters:**
@ -573,7 +573,7 @@ Converts a string representation of a number into a floating-point number.
**Usage:** **Usage:**
```tomo ```tomo
from_text(text: Text, the_rest: Text = "!&Text") -> Num from_text(text: Text, the_rest: Text = "!&Text" -> Num)
``` ```
**Parameters:** **Parameters:**
@ -601,7 +601,7 @@ Computes the Euclidean norm, \( \sqrt{x^2 + y^2} \), of two numbers.
**Usage:** **Usage:**
```tomo ```tomo
hypot(x: Num, y: Num) -> Num hypot(x: Num, y: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -627,7 +627,7 @@ Checks if a number is finite.
**Usage:** **Usage:**
```tomo ```tomo
isfinite(n: Num) -> Bool isfinite(n: Num -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -654,7 +654,7 @@ Checks if a number is infinite.
**Usage:** **Usage:**
```tomo ```tomo
isinf(n: Num) -> Bool isinf(n: Num -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -681,7 +681,7 @@ Checks if a number is NaN (Not a Number).
**Usage:** **Usage:**
```tomo ```tomo
isnan(n: Num) -> Bool isnan(n: Num -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -708,7 +708,7 @@ Computes the Bessel function of the first kind of order 0.
**Usage:** **Usage:**
```tomo ```tomo
j0(x: Num) -> Num j0(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -733,7 +733,7 @@ Computes the Bessel function of the first kind of order 1.
**Usage:** **Usage:**
```tomo ```tomo
j1(x: Num) -> Num j1(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -758,7 +758,7 @@ Computes the base-10 logarithm of a number.
**Usage:** **Usage:**
```tomo ```tomo
log10(x: Num) -> Num log10(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -783,7 +783,7 @@ Computes \( \log(1 + x) \) for a number.
**Usage:** **Usage:**
```tomo ```tomo
log1p(x: Num) -> Num log1p(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -808,7 +808,7 @@ Computes the base-2 logarithm of a number.
**Usage:** **Usage:**
```tomo ```tomo
log2(x: Num) -> Num log2(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -833,7 +833,7 @@ Computes the natural logarithm (base \( e \)) of a number.
**Usage:** **Usage:**
```tomo ```tomo
log(x: Num) -> Num log(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -858,7 +858,7 @@ Computes the binary exponent (base-2 logarithm) of a number.
**Usage:** **Usage:**
```tomo ```tomo
logb(x: Num) -> Num logb(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -883,7 +883,7 @@ Interpolates between two numbers based on a given amount.
**Usage:** **Usage:**
```tomo ```tomo
mix(amount: Num, x: Num, y: Num) -> Num mix(amount: Num, x: Num, y: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -912,7 +912,7 @@ Generates a NaN (Not a Number) value.
**Usage:** **Usage:**
```tomo ```tomo
nan(tag: Text = "") -> Num nan(tag: Text = "" -> Num)
``` ```
**Parameters:** **Parameters:**
@ -939,7 +939,7 @@ small enough, they are considered near each other.
**Usage:** **Usage:**
```tomo ```tomo
near(x: Num, y: Num, ratio: Num = 1e-9, min_epsilon: Num = 1e-9) -> Bool near(x: Num, y: Num, ratio: Num = 1e-9, min_epsilon: Num = 1e-9 -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -973,7 +973,7 @@ Computes the next representable value after a given number towards a specified d
**Usage:** **Usage:**
```tomo ```tomo
nextafter(x: Num, y: Num) -> Num nextafter(x: Num, y: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -999,7 +999,7 @@ Generates a random floating-point number.
**Usage:** **Usage:**
```tomo ```tomo
random() -> Num random(->Num)
``` ```
**Parameters:** **Parameters:**
@ -1023,7 +1023,7 @@ Rounds a number to the nearest integer, with ties rounded to the nearest even in
**Usage:** **Usage:**
```tomo ```tomo
rint(x: Num) -> Num rint(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1050,7 +1050,7 @@ Rounds a number to the nearest whole number integer.
**Usage:** **Usage:**
```tomo ```tomo
round(x: Num) -> Num round(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1077,7 +1077,7 @@ Formats a number in scientific notation with a specified precision.
**Usage:** **Usage:**
```tomo ```tomo
scientific(n: Num, precision: Int = 0) -> Text scientific(n: Num, precision: Int = 0 -> Text)
``` ```
**Parameters:** **Parameters:**
@ -1103,7 +1103,7 @@ Extracts the significand (or mantissa) of a number.
**Usage:** **Usage:**
```tomo ```tomo
significand(x: Num) -> Num significand(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1128,7 +1128,7 @@ Computes the sine of a number (angle in radians).
**Usage:** **Usage:**
```tomo ```tomo
sin(x: Num) -> Num sin(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1153,7 +1153,7 @@ Computes the hyperbolic sine of a number.
**Usage:** **Usage:**
```tomo ```tomo
sinh(x: Num) -> Num sinh(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1178,7 +1178,7 @@ Computes the square root of a number.
**Usage:** **Usage:**
```tomo ```tomo
sqrt(x: Num) -> Num sqrt(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1203,7 +1203,7 @@ Computes the tangent of a number (angle in radians).
**Usage:** **Usage:**
```tomo ```tomo
tan(x: Num) -> Num tan(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1228,7 +1228,7 @@ Computes the hyperbolic tangent of a number.
**Usage:** **Usage:**
```tomo ```tomo
tanh(x: Num) -> Num tanh(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1253,7 +1253,7 @@ Computes the gamma function of a number.
**Usage:** **Usage:**
```tomo ```tomo
tgamma(x: Num) -> Num tgamma(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1278,7 +1278,7 @@ Truncates a number to the nearest integer towards zero.
**Usage:** **Usage:**
```tomo ```tomo
trunc(x: Num) -> Num trunc(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1305,7 +1305,7 @@ Computes the Bessel function of the second kind of order 0.
**Usage:** **Usage:**
```tomo ```tomo
y0(x: Num) -> Num y0(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1330,7 +1330,7 @@ Computes the Bessel function of the second kind of order 1.
**Usage:** **Usage:**
```tomo ```tomo
y1(x: Num) -> Num y1(x: Num -> Num)
``` ```
**Parameters:** **Parameters:**
@ -1356,7 +1356,7 @@ that range.
**Usage:** **Usage:**
```tomo ```tomo
clamped(x, low, high: Num) -> Num clamped(x, low, high: Num -> Num)
``` ```
**Parameters:** **Parameters:**

View File

@ -45,7 +45,7 @@ it doesn't already exist. Failure to write will result in a runtime error.
**Usage:** **Usage:**
```markdown ```markdown
append(path: Path, text: Text, permissions: Int32 = 0o644[32]) -> Void append(path: Path, text: Text, permissions: Int32 = 0o644[32] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -72,7 +72,7 @@ it doesn't already exist. Failure to write will result in a runtime error.
**Usage:** **Usage:**
```markdown ```markdown
append_bytes(path: Path, bytes: [Byte], permissions: Int32 = 0o644[32]) -> Void append_bytes(path: Path, bytes: [Byte], permissions: Int32 = 0o644[32] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -98,7 +98,7 @@ Returns the base name of the file or directory at the specified path.
**Usage:** **Usage:**
```markdown ```markdown
base_name(path: Path) -> Text base_name(path: Path -> Text)
``` ```
**Parameters:** **Parameters:**
@ -124,7 +124,7 @@ or returns a null value if the file could not be opened.
**Usage:** **Usage:**
```markdown ```markdown
by_line(path: Path) -> (func()->Text?)? by_line(path: Path -> (func()->Text?)?)
``` ```
**Parameters:** **Parameters:**
@ -158,7 +158,7 @@ Returns a list of children (files and directories) within the directory at the s
**Usage:** **Usage:**
```markdown ```markdown
children(path: Path, include_hidden=no) -> [Path] children(path: Path, include_hidden=no -> [Path])
``` ```
**Parameters:** **Parameters:**
@ -185,7 +185,7 @@ any of the parent directories do not exist, they will be created as needed.
**Usage:** **Usage:**
```markdown ```markdown
create_directory(path: Path, permissions=0o755[32]) -> Void create_directory(path: Path, permissions=0o755[32] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -210,7 +210,7 @@ Checks if a file or directory exists at the specified path.
**Usage:** **Usage:**
```markdown ```markdown
exists(path: Path) -> Bool exists(path: Path -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -235,7 +235,7 @@ Returns the file extension of the file at the specified path. Optionally returns
**Usage:** **Usage:**
```markdown ```markdown
extension(path: Path, full=yes) -> Text extension(path: Path, full=yes -> Text)
``` ```
**Parameters:** **Parameters:**
@ -269,7 +269,7 @@ Returns a list of files within the directory at the specified path. Optionally i
**Usage:** **Usage:**
```markdown ```markdown
files(path: Path, include_hidden=no) -> [Path] files(path: Path, include_hidden=no -> [Path])
``` ```
**Parameters:** **Parameters:**
@ -295,7 +295,7 @@ Checks if the path represents a directory. Optionally follows symbolic links.
**Usage:** **Usage:**
```markdown ```markdown
is_directory(path: Path, follow_symlinks=yes) -> Bool is_directory(path: Path, follow_symlinks=yes -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -324,7 +324,7 @@ Checks if the path represents a file. Optionally follows symbolic links.
**Usage:** **Usage:**
```markdown ```markdown
is_file(path: Path, follow_symlinks=yes) -> Bool is_file(path: Path, follow_symlinks=yes -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -353,7 +353,7 @@ Checks if the path represents a socket. Optionally follows symbolic links.
**Usage:** **Usage:**
```markdown ```markdown
is_socket(path: Path, follow_symlinks=yes) -> Bool is_socket(path: Path, follow_symlinks=yes -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -379,7 +379,7 @@ Checks if the path represents a symbolic link.
**Usage:** **Usage:**
```markdown ```markdown
is_symlink(path: Path) -> Bool is_symlink(path: Path -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -404,7 +404,7 @@ Returns the parent directory of the file or directory at the specified path.
**Usage:** **Usage:**
```markdown ```markdown
parent(path: Path) -> Path parent(path: Path -> Path)
``` ```
**Parameters:** **Parameters:**
@ -430,7 +430,7 @@ file could not be read.
**Usage:** **Usage:**
```markdown ```markdown
read(path: Path) -> Text? read(path: Path -> Text?)
``` ```
**Parameters:** **Parameters:**
@ -460,7 +460,7 @@ file could not be read.
**Usage:** **Usage:**
```markdown ```markdown
read_bytes(path: Path) -> [Byte]? read_bytes(path: Path -> [Byte]?)
``` ```
**Parameters:** **Parameters:**
@ -489,7 +489,7 @@ Returns the path relative to a given base path. By default, the base path is the
**Usage:** **Usage:**
```markdown ```markdown
relative(path: Path, relative_to=(./)) -> Path relative(path: Path, relative_to=(./) -> Path)
``` ```
**Parameters:** **Parameters:**
@ -515,7 +515,7 @@ Removes the file or directory at the specified path. A runtime error is raised i
**Usage:** **Usage:**
```markdown ```markdown
remove(path: Path, ignore_missing=no) -> Void remove(path: Path, ignore_missing=no -> Void)
``` ```
**Parameters:** **Parameters:**
@ -540,7 +540,7 @@ Resolves the absolute path of the given path relative to a base path. By default
**Usage:** **Usage:**
```markdown ```markdown
resolved(path: Path, relative_to=(./)) -> Path resolved(path: Path, relative_to=(./) -> Path)
``` ```
**Parameters:** **Parameters:**
@ -569,7 +569,7 @@ Returns a list of subdirectories within the directory at the specified path. Opt
**Usage:** **Usage:**
```markdown ```markdown
subdirectories(path: Path, include_hidden=no) -> [Path] subdirectories(path: Path, include_hidden=no -> [Path])
``` ```
**Parameters:** **Parameters:**
@ -598,7 +598,7 @@ Generates a unique directory path based on the given path. Useful for creating t
**Usage:** **Usage:**
```markdown ```markdown
unique_directory(path: Path) -> Path unique_directory(path: Path -> Path)
``` ```
**Parameters:** **Parameters:**
@ -629,7 +629,7 @@ writing cannot be successfully completed, a runtime error is raised.
**Usage:** **Usage:**
```markdown ```markdown
write(path: Path, text: Text, permissions=0o644[32]) -> Void write(path: Path, text: Text, permissions=0o644[32] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -657,7 +657,7 @@ writing cannot be successfully completed, a runtime error is raised.
**Usage:** **Usage:**
```markdown ```markdown
write(path: Path, bytes: [Byte], permissions=0o644[32]) -> Void write(path: Path, bytes: [Byte], permissions=0o644[32] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -685,7 +685,7 @@ files.
**Usage:** **Usage:**
```markdown ```markdown
write_unique(path: Path, text: Text) -> Path write_unique(path: Path, text: Text -> Path)
``` ```
**Parameters:** **Parameters:**
@ -717,7 +717,7 @@ files.
**Usage:** **Usage:**
```markdown ```markdown
write_unique_bytes(path: Path, bytes: [Byte]) -> Path write_unique_bytes(path: Path, bytes: [Byte] -> Path)
``` ```
**Parameters:** **Parameters:**

View File

@ -20,7 +20,7 @@ Returns a reversed copy of the range.
**Usage:** **Usage:**
```tomo ```tomo
reversed(range: Range) -> Range reversed(range: Range -> Range)
``` ```
**Parameters:** **Parameters:**
@ -45,7 +45,7 @@ Creates a new range with a specified step value.
**Usage:** **Usage:**
```tomo ```tomo
by(range: Range, step: Int) -> Range by(range: Range, step: Int -> Range)
``` ```
**Parameters:** **Parameters:**

View File

@ -82,7 +82,7 @@ Checks if the set contains a specified item.
**Usage:** **Usage:**
```tomo ```tomo
has(set:{T}, item:T) -> Bool has(set:{T}, item:T -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -108,7 +108,7 @@ Adds an item to the set.
**Usage:** **Usage:**
```tomo ```tomo
add(set:{T}, item: T) -> Void add(set:{T}, item: T -> Void)
``` ```
**Parameters:** **Parameters:**
@ -133,7 +133,7 @@ Adds multiple items to the set.
**Usage:** **Usage:**
```tomo ```tomo
add_all(set:&{T}, items: [T]) -> Void add_all(set:&{T}, items: [T] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -158,7 +158,7 @@ Removes an item from the set.
**Usage:** **Usage:**
```tomo ```tomo
remove(set:&{T}, item: T) -> Void remove(set:&{T}, item: T -> Void)
``` ```
**Parameters:** **Parameters:**
@ -183,7 +183,7 @@ Removes multiple items from the set.
**Usage:** **Usage:**
```tomo ```tomo
remove_all(set:&{T}, items: [T]) -> Void remove_all(set:&{T}, items: [T] -> Void)
``` ```
**Parameters:** **Parameters:**
@ -208,7 +208,7 @@ Removes all items from the set.
**Usage:** **Usage:**
```tomo ```tomo
clear(set:&{T}) -> Void clear(set:&{T} -> Void)
``` ```
**Parameters:** **Parameters:**
@ -232,7 +232,7 @@ Creates a new set that is the union of the original set and another set.
**Usage:** **Usage:**
```tomo ```tomo
with(set:{T}, other: {T}) -> {T} with(set:{T}, other: {T} -> {T})
``` ```
**Parameters:** **Parameters:**
@ -258,7 +258,7 @@ Creates a new set with items that are in both the original set and another set.
**Usage:** **Usage:**
```tomo ```tomo
overlap(set:{T}, other: {T}) -> {T} overlap(set:{T}, other: {T} -> {T})
``` ```
**Parameters:** **Parameters:**
@ -284,7 +284,7 @@ Creates a new set with items from the original set but without items from anothe
**Usage:** **Usage:**
```tomo ```tomo
without(set:{T}, other: {T}) -> {T} without(set:{T}, other: {T} -> {T})
``` ```
**Parameters:** **Parameters:**
@ -310,7 +310,7 @@ Checks if the set is a subset of another set.
**Usage:** **Usage:**
```tomo ```tomo
set:is_subset_of(other: {T}, strict: Bool = no) -> Bool set:is_subset_of(other: {T}, strict: Bool = no -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -337,7 +337,7 @@ Checks if the set is a superset of another set.
**Usage:** **Usage:**
```tomo ```tomo
is_superset_of(set:{T}, other: {T}, strict: Bool = no) -> Bool is_superset_of(set:{T}, other: {T}, strict: Bool = no -> Bool)
``` ```
**Parameters:** **Parameters:**

View File

@ -118,7 +118,7 @@ not already in the table, its value will be assumed to be zero.
**Usage:** **Usage:**
```markdown ```markdown
bump(t:{K:V}, key: K, amount: Int = 1) -> Void bump(t:{K:V}, key: K, amount: Int = 1 -> Void)
``` ```
**Parameters:** **Parameters:**
@ -148,7 +148,7 @@ Removes all key-value pairs from the table.
**Usage:** **Usage:**
```markdown ```markdown
t:clear() -> Void t:clear()
``` ```
**Parameters:** **Parameters:**
@ -172,7 +172,7 @@ Retrieves the value associated with a key, or returns null if the key is not pre
**Usage:** **Usage:**
```markdown ```markdown
t:get(key: K) -> V? t:get(key: K -> V?)
``` ```
**Parameters:** **Parameters:**
@ -208,7 +208,7 @@ Checks if the table contains a specified key.
**Usage:** **Usage:**
```markdown ```markdown
has(t:{K:V}, key: K) -> Bool has(t:{K:V}, key: K -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -236,7 +236,7 @@ Removes the key-value pair associated with a specified key.
**Usage:** **Usage:**
```markdown ```markdown
remove(t:{K:V}, key: K) -> Void remove(t:{K:V}, key: K -> Void)
``` ```
**Parameters:** **Parameters:**
@ -264,7 +264,7 @@ Sets or updates the value associated with a specified key.
**Usage:** **Usage:**
```markdown ```markdown
set(t:{K:V}, key: K, value: V) -> Void set(t:{K:V}, key: K, value: V -> Void)
``` ```
**Parameters:** **Parameters:**

View File

@ -402,7 +402,7 @@ Converts a `Text` value to a C-style string.
**Usage:** **Usage:**
```tomo ```tomo
as_c_string(text: Text) -> CString as_c_string(text: Text -> CString)
``` ```
**Parameters:** **Parameters:**
@ -428,7 +428,7 @@ the text.
**Usage:** **Usage:**
```tomo ```tomo
utf8_bytes(text: Text) -> [Byte] utf8_bytes(text: Text -> [Byte])
``` ```
**Parameters:** **Parameters:**
@ -453,7 +453,7 @@ Returns an array of the names of each codepoint in the text.
**Usage:** **Usage:**
```tomo ```tomo
codepoint_names(text: Text) -> [Text] codepoint_names(text: Text -> [Text])
``` ```
**Parameters:** **Parameters:**
@ -478,7 +478,7 @@ Returns an array of Unicode code points for UTF32 encoding of the text.
**Usage:** **Usage:**
```tomo ```tomo
utf32_codepoints(text: Text) -> [Int32] utf32_codepoints(text: Text -> [Int32])
``` ```
**Parameters:** **Parameters:**
@ -503,7 +503,7 @@ Checks if the `Text` ends with a literal suffix text.
**Usage:** **Usage:**
```tomo ```tomo
ends_with(text: Text, suffix: Text) -> Bool ends_with(text: Text, suffix: Text -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -529,7 +529,7 @@ Converts a C-style string to a `Text` value.
**Usage:** **Usage:**
```tomo ```tomo
from_c_string(str: CString) -> Text from_c_string(str: CString -> Text)
``` ```
**Parameters:** **Parameters:**
@ -556,7 +556,7 @@ resulting text's codepoints may not exactly match the input codepoints.
**Usage:** **Usage:**
```tomo ```tomo
from_codepoint_names(codepoint_names: [Text]) -> [Text] from_codepoint_names(codepoint_names: [Text] -> [Text])
``` ```
**Parameters:** **Parameters:**
@ -589,7 +589,7 @@ match the input codepoints.
**Usage:** **Usage:**
```tomo ```tomo
from_codepoint_names(codepoints: [Int32]) -> [Text] from_codepoint_names(codepoints: [Int32] -> [Text])
``` ```
**Parameters:** **Parameters:**
@ -616,7 +616,7 @@ match the input.
**Usage:** **Usage:**
```tomo ```tomo
from_codepoint_names(codepoints: [Int32]) -> [Text] from_codepoint_names(codepoints: [Int32] -> [Text])
``` ```
**Parameters:** **Parameters:**
@ -642,7 +642,7 @@ See: [Patterns](#Patterns) for more information on patterns.
**Usage:** **Usage:**
```tomo ```tomo
find(text: Text, pattern: Pattern, start: Int = 1, length: &Int64? = !&Int64) -> Int find(text: Text, pattern: Pattern, start: Int = 1, length: &Int64? = !&Int64 -> Int)
``` ```
**Parameters:** **Parameters:**
@ -685,7 +685,7 @@ See: [Patterns](#Patterns) for more information on patterns.
**Usage:** **Usage:**
```tomo ```tomo
find_all(text: Text, pattern: Pattern) -> [Text] find_all(text: Text, pattern: Pattern -> [Text])
``` ```
**Parameters:** **Parameters:**
@ -727,7 +727,7 @@ Checks if the `Text` contains a target pattern (see: [Patterns](#Patterns)).
**Usage:** **Usage:**
```tomo ```tomo
has(text: Text, pattern: Pattern) -> Bool has(text: Text, pattern: Pattern -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -759,7 +759,7 @@ Joins an array of text pieces with a specified glue.
**Usage:** **Usage:**
```tomo ```tomo
join(glue: Text, pieces: [Text]) -> Text join(glue: Text, pieces: [Text] -> Text)
``` ```
**Parameters:** **Parameters:**
@ -786,7 +786,7 @@ ignoring trailing newlines, and handling `\r\n` the same as `\n`.
**Usage:** **Usage:**
```tomo ```tomo
split(text: Text) -> [Text] split(text: Text -> [Text])
``` ```
**Parameters:** **Parameters:**
@ -819,7 +819,7 @@ Converts all characters in the text to lowercase.
**Usage:** **Usage:**
```tomo ```tomo
lower(text: Text) -> Text lower(text: Text -> Text)
``` ```
**Parameters:** **Parameters:**
@ -846,7 +846,7 @@ doesn't match the pattern.
**Usage:** **Usage:**
```tomo ```tomo
matches(text: Text, pattern: Pattern) -> [Text] matches(text: Text, pattern: Pattern -> [Text])
``` ```
**Parameters:** **Parameters:**
@ -877,7 +877,7 @@ calling the given function on that text.
**Usage:** **Usage:**
```tomo ```tomo
map(text: Text, pattern: Pattern, fn: func(text:Text)->Text) -> Text map(text: Text, pattern: Pattern, fn: func(text:Text)->Text -> Text)
``` ```
**Parameters:** **Parameters:**
@ -907,7 +907,7 @@ Formats the text as a quoted string.
**Usage:** **Usage:**
```tomo ```tomo
quoted(text: Text, color: Bool = no) -> Text quoted(text: Text, color: Bool = no -> Text)
``` ```
**Parameters:** **Parameters:**
@ -933,7 +933,7 @@ Repeat some text multiple times.
**Usage:** **Usage:**
```tomo ```tomo
repeat(text: Text, count:Int) -> Text repeat(text: Text, count:Int -> Text)
``` ```
**Parameters:** **Parameters:**
@ -961,7 +961,7 @@ See [Patterns](#patterns) for more information about patterns.
**Usage:** **Usage:**
```tomo ```tomo
replace(text: Text, pattern: Pattern, replacement: Text, backref: Pattern = $/\/, recursive: Bool = yes) -> Text replace(text: Text, pattern: Pattern, replacement: Text, backref: Pattern = $/\/, recursive: Bool = yes -> Text)
``` ```
**Parameters:** **Parameters:**
@ -1030,7 +1030,7 @@ See [`replace()`](#replace) for more information about replacement behavior.
**Usage:** **Usage:**
```tomo ```tomo
replace_all(replacements:{Pattern:Text}, backref: Pattern = $/\/) -> Text replace_all(replacements:{Pattern:Text}, backref: Pattern = $/\/ -> Text)
``` ```
**Parameters:** **Parameters:**
@ -1075,7 +1075,7 @@ See [Patterns](#patterns) for more information about patterns.
**Usage:** **Usage:**
```tomo ```tomo
split(text: Text, pattern: Pattern = "") -> [Text] split(text: Text, pattern: Pattern = "" -> [Text])
``` ```
**Parameters:** **Parameters:**
@ -1111,7 +1111,7 @@ Checks if the `Text` starts with a literal prefix text.
**Usage:** **Usage:**
```tomo ```tomo
starts_with(text: Text, prefix: Text) -> Bool starts_with(text: Text, prefix: Text -> Bool)
``` ```
**Parameters:** **Parameters:**
@ -1137,7 +1137,7 @@ Converts the text to title case (capitalizing the first letter of each word).
**Usage:** **Usage:**
```tomo ```tomo
title(text: Text) -> Text title(text: Text -> Text)
``` ```
**Parameters:** **Parameters:**
@ -1163,7 +1163,7 @@ See [Patterns](#patterns) for more information about patterns.
**Usage:** **Usage:**
```tomo ```tomo
trim(text: Text, pattern: Pattern = $/{whitespace/, trim_left: Bool = yes, trim_right: Bool = yes) -> Text trim(text: Text, pattern: Pattern = $/{whitespace/, trim_left: Bool = yes, trim_right: Bool = yes -> Text)
``` ```
**Parameters:** **Parameters:**
@ -1197,7 +1197,7 @@ Converts all characters in the text to uppercase.
**Usage:** **Usage:**
```tomo ```tomo
upper(text: Text) -> Text upper(text: Text -> Text)
``` ```
**Parameters:** **Parameters:**

View File

@ -13,7 +13,7 @@ Creates a new thread to execute a specified function.
**Usage:** **Usage:**
```tomo ```tomo
Thread.new(fn: func() -> Void) -> Thread Thread.new(fn: func(->Void) -> Thread)
``` ```
**Parameters:** **Parameters:**
@ -47,7 +47,7 @@ Requests the cancellation of a specified thread.
**Usage:** **Usage:**
```tomo ```tomo
cancel(thread: Thread) -> Void cancel(thread: Thread)
``` ```
**Parameters:** **Parameters:**
@ -71,7 +71,7 @@ Waits for a specified thread to terminate.
**Usage:** **Usage:**
```tomo ```tomo
join(thread: Thread) -> Void join(thread: Thread)
``` ```
**Parameters:** **Parameters:**
@ -95,7 +95,7 @@ Detaches a specified thread, allowing it to run independently.
**Usage:** **Usage:**
```tomo ```tomo
detach(thread: Thread) -> Void detach(thread: Thread)
``` ```
**Parameters:** **Parameters:**

View File

@ -88,130 +88,130 @@ env_t *new_compilation_unit(CORD libname)
{"Void", Type(VoidType), "Void_t", "Void$info", {}}, {"Void", Type(VoidType), "Void_t", "Void$info", {}},
{"Memory", Type(MemoryType), "Memory_t", "Memory$info", {}}, {"Memory", Type(MemoryType), "Memory_t", "Memory$info", {}},
{"Bool", Type(BoolType), "Bool_t", "Bool$info", TypedArray(ns_entry_t, {"Bool", Type(BoolType), "Bool_t", "Bool$info", TypedArray(ns_entry_t,
{"from_text", "Bool$from_text", "func(text:Text)->Bool?"}, {"from_text", "Bool$from_text", "func(text:Text -> Bool?)"},
{"random", "Bool$random", "func(p=0.5)->Bool"}, {"random", "Bool$random", "func(p=0.5 -> Bool)"},
)}, )},
{"Byte", Type(ByteType), "Byte_t", "Byte$info", TypedArray(ns_entry_t, {"Byte", Type(ByteType), "Byte_t", "Byte$info", TypedArray(ns_entry_t,
{"max", "Byte$max", "Byte"}, {"max", "Byte$max", "Byte"},
{"min", "Byte$min", "Byte"}, {"min", "Byte$min", "Byte"},
{"random", "Byte$random", "func(min=Byte.min, max=Byte.max)->Byte"}, {"random", "Byte$random", "func(min=Byte.min, max=Byte.max -> Byte)"},
)}, )},
{"Int", Type(BigIntType), "Int_t", "Int$info", TypedArray(ns_entry_t, {"Int", Type(BigIntType), "Int_t", "Int$info", TypedArray(ns_entry_t,
{"abs", "Int$abs", "func(x:Int)->Int"}, {"abs", "Int$abs", "func(x:Int -> Int)"},
{"bit_and", "Int$bit_and", "func(x,y:Int)->Int"}, {"bit_and", "Int$bit_and", "func(x,y:Int -> Int)"},
{"bit_or", "Int$bit_or", "func(x,y:Int)->Int"}, {"bit_or", "Int$bit_or", "func(x,y:Int -> Int)"},
{"bit_xor", "Int$bit_xor", "func(x,y:Int)->Int"}, {"bit_xor", "Int$bit_xor", "func(x,y:Int -> Int)"},
{"clamped", "Int$clamped", "func(x,low,high:Int)->Int"}, {"clamped", "Int$clamped", "func(x,low,high:Int -> Int)"},
{"divided_by", "Int$divided_by", "func(x,y:Int)->Int"}, {"divided_by", "Int$divided_by", "func(x,y:Int -> Int)"},
{"format", "Int$format", "func(i:Int, digits=0)->Text"}, {"format", "Int$format", "func(i:Int, digits=0 -> Text)"},
{"from_text", "Int$from_text", "func(text:Text)->Int?"}, {"from_text", "Int$from_text", "func(text:Text -> Int?)"},
{"hex", "Int$hex", "func(i:Int, digits=0, uppercase=yes, prefix=yes)->Text"}, {"hex", "Int$hex", "func(i:Int, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"is_prime", "Int$is_prime", "func(x:Int,reps=50)->Bool"}, {"is_prime", "Int$is_prime", "func(x:Int,reps=50 -> Bool)"},
{"left_shifted", "Int$left_shifted", "func(x,y:Int)->Int"}, {"left_shifted", "Int$left_shifted", "func(x,y:Int -> Int)"},
{"minus", "Int$minus", "func(x,y:Int)->Int"}, {"minus", "Int$minus", "func(x,y:Int -> Int)"},
{"modulo", "Int$modulo", "func(x,y:Int)->Int"}, {"modulo", "Int$modulo", "func(x,y:Int -> Int)"},
{"modulo1", "Int$modulo1", "func(x,y:Int)->Int"}, {"modulo1", "Int$modulo1", "func(x,y:Int -> Int)"},
{"negated", "Int$negated", "func(x:Int)->Int"}, {"negated", "Int$negated", "func(x:Int -> Int)"},
{"negative", "Int$negative", "func(x:Int)->Int"}, {"negative", "Int$negative", "func(x:Int -> Int)"},
{"next_prime", "Int$next_prime", "func(x:Int)->Int"}, {"next_prime", "Int$next_prime", "func(x:Int -> Int)"},
{"octal", "Int$octal", "func(i:Int, digits=0, prefix=yes)->Text"}, {"octal", "Int$octal", "func(i:Int, digits=0, prefix=yes -> Text)"},
{"plus", "Int$plus", "func(x,y:Int)->Int"}, {"plus", "Int$plus", "func(x,y:Int -> Int)"},
{"power", "Int$power", "func(base:Int,exponent:Int)->Int"}, {"power", "Int$power", "func(base:Int,exponent:Int -> Int)"},
{"prev_prime", "Int$prev_prime", "func(x:Int)->Int"}, {"prev_prime", "Int$prev_prime", "func(x:Int -> Int)"},
{"random", "Int$random", "func(min,max:Int)->Int"}, {"random", "Int$random", "func(min,max:Int -> Int)"},
{"right_shifted", "Int$right_shifted", "func(x,y:Int)->Int"}, {"right_shifted", "Int$right_shifted", "func(x,y:Int -> Int)"},
{"sqrt", "Int$sqrt", "func(x:Int)->Int"}, {"sqrt", "Int$sqrt", "func(x:Int -> Int)"},
{"times", "Int$times", "func(x,y:Int)->Int"}, {"times", "Int$times", "func(x,y:Int -> Int)"},
{"to", "Int$to", "func(from:Int,to:Int)->Range"}, {"to", "Int$to", "func(from:Int,to:Int -> Range)"},
)}, )},
{"Int64", Type(IntType, .bits=TYPE_IBITS64), "Int64_t", "Int64$info", TypedArray(ns_entry_t, {"Int64", Type(IntType, .bits=TYPE_IBITS64), "Int64_t", "Int64$info", TypedArray(ns_entry_t,
{"abs", "labs", "func(i:Int64)->Int64"}, {"abs", "labs", "func(i:Int64 -> Int64)"},
{"bits", "Int64$bits", "func(x:Int64)->[Bool]"}, {"bits", "Int64$bits", "func(x:Int64 -> [Bool])"},
{"clamped", "Int64$clamped", "func(x,low,high:Int64)->Int64"}, {"clamped", "Int64$clamped", "func(x,low,high:Int64 -> Int64)"},
{"divided_by", "Int64$divided_by", "func(x,y:Int64)->Int64"}, {"divided_by", "Int64$divided_by", "func(x,y:Int64 -> Int64)"},
{"format", "Int64$format", "func(i:Int64, digits=0)->Text"}, {"format", "Int64$format", "func(i:Int64, digits=0 -> Text)"},
{"from_text", "Int64$from_text", "func(text:Text)->Int64?"}, {"from_text", "Int64$from_text", "func(text:Text -> Int64?)"},
{"hex", "Int64$hex", "func(i:Int64, digits=0, uppercase=yes, prefix=yes)->Text"}, {"hex", "Int64$hex", "func(i:Int64, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"max", "Int64$max", "Int64"}, {"max", "Int64$max", "Int64"},
{"min", "Int64$min", "Int64"}, {"min", "Int64$min", "Int64"},
{"modulo", "Int64$modulo", "func(x,y:Int64)->Int64"}, {"modulo", "Int64$modulo", "func(x,y:Int64 -> Int64)"},
{"modulo1", "Int64$modulo1", "func(x,y:Int64)->Int64"}, {"modulo1", "Int64$modulo1", "func(x,y:Int64 -> Int64)"},
{"octal", "Int64$octal", "func(i:Int64, digits=0, prefix=yes)->Text"}, {"octal", "Int64$octal", "func(i:Int64, digits=0, prefix=yes -> Text)"},
{"to", "Int64$to", "func(from:Int64,to:Int64)->Range"}, {"to", "Int64$to", "func(from:Int64,to:Int64 -> Range)"},
// Must be defined after min/max: // Must be defined after min/max:
{"random", "Int64$random", "func(min=Int64.min, max=Int64.max)->Int64"}, {"random", "Int64$random", "func(min=Int64.min, max=Int64.max -> Int64)"},
)}, )},
{"Int32", Type(IntType, .bits=TYPE_IBITS32), "Int32_t", "Int32$info", TypedArray(ns_entry_t, {"Int32", Type(IntType, .bits=TYPE_IBITS32), "Int32_t", "Int32$info", TypedArray(ns_entry_t,
{"abs", "abs", "func(i:Int32)->Int32"}, {"abs", "abs", "func(i:Int32 -> Int32)"},
{"bits", "Int32$bits", "func(x:Int32)->[Bool]"}, {"bits", "Int32$bits", "func(x:Int32 -> [Bool])"},
{"clamped", "Int32$clamped", "func(x,low,high:Int32)->Int32"}, {"clamped", "Int32$clamped", "func(x,low,high:Int32 -> Int32)"},
{"divided_by", "Int32$divided_by", "func(x,y:Int32)->Int32"}, {"divided_by", "Int32$divided_by", "func(x,y:Int32 -> Int32)"},
{"format", "Int32$format", "func(i:Int32, digits=0)->Text"}, {"format", "Int32$format", "func(i:Int32, digits=0 -> Text)"},
{"from_text", "Int32$from_text", "func(text:Text)->Int32?"}, {"from_text", "Int32$from_text", "func(text:Text -> Int32?)"},
{"hex", "Int32$hex", "func(i:Int32, digits=0, uppercase=yes, prefix=yes)->Text"}, {"hex", "Int32$hex", "func(i:Int32, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"max", "Int32$max", "Int32"}, {"max", "Int32$max", "Int32"},
{"min", "Int32$min", "Int32"}, {"min", "Int32$min", "Int32"},
{"modulo", "Int32$modulo", "func(x,y:Int32)->Int32"}, {"modulo", "Int32$modulo", "func(x,y:Int32 -> Int32)"},
{"modulo1", "Int32$modulo1", "func(x,y:Int32)->Int32"}, {"modulo1", "Int32$modulo1", "func(x,y:Int32 -> Int32)"},
{"octal", "Int32$octal", "func(i:Int32, digits=0, prefix=yes)->Text"}, {"octal", "Int32$octal", "func(i:Int32, digits=0, prefix=yes -> Text)"},
{"to", "Int32$to", "func(from:Int32,to:Int32)->Range"}, {"to", "Int32$to", "func(from:Int32,to:Int32 -> Range)"},
// Must be defined after min/max: // Must be defined after min/max:
{"random", "Int32$random", "func(min=Int32.min, max=Int32.max)->Int32"}, {"random", "Int32$random", "func(min=Int32.min, max=Int32.max -> Int32)"},
)}, )},
{"Int16", Type(IntType, .bits=TYPE_IBITS16), "Int16_t", "Int16$info", TypedArray(ns_entry_t, {"Int16", Type(IntType, .bits=TYPE_IBITS16), "Int16_t", "Int16$info", TypedArray(ns_entry_t,
{"abs", "abs", "func(i:Int16)->Int16"}, {"abs", "abs", "func(i:Int16 -> Int16)"},
{"bits", "Int16$bits", "func(x:Int16)->[Bool]"}, {"bits", "Int16$bits", "func(x:Int16 -> [Bool])"},
{"clamped", "Int16$clamped", "func(x,low,high:Int16)->Int16"}, {"clamped", "Int16$clamped", "func(x,low,high:Int16 -> Int16)"},
{"divided_by", "Int16$divided_by", "func(x,y:Int16)->Int16"}, {"divided_by", "Int16$divided_by", "func(x,y:Int16 -> Int16)"},
{"format", "Int16$format", "func(i:Int16, digits=0)->Text"}, {"format", "Int16$format", "func(i:Int16, digits=0 -> Text)"},
{"from_text", "Int16$from_text", "func(text:Text)->Int16?"}, {"from_text", "Int16$from_text", "func(text:Text -> Int16?)"},
{"hex", "Int16$hex", "func(i:Int16, digits=0, uppercase=yes, prefix=yes)->Text"}, {"hex", "Int16$hex", "func(i:Int16, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"max", "Int16$max", "Int16"}, {"max", "Int16$max", "Int16"},
{"min", "Int16$min", "Int16"}, {"min", "Int16$min", "Int16"},
{"modulo", "Int16$modulo", "func(x,y:Int16)->Int16"}, {"modulo", "Int16$modulo", "func(x,y:Int16 -> Int16)"},
{"modulo1", "Int16$modulo1", "func(x,y:Int16)->Int16"}, {"modulo1", "Int16$modulo1", "func(x,y:Int16 -> Int16)"},
{"octal", "Int16$octal", "func(i:Int16, digits=0, prefix=yes)->Text"}, {"octal", "Int16$octal", "func(i:Int16, digits=0, prefix=yes -> Text)"},
{"to", "Int16$to", "func(from:Int16,to:Int16)->Range"}, {"to", "Int16$to", "func(from:Int16,to:Int16 -> Range)"},
// Must be defined after min/max: // Must be defined after min/max:
{"random", "Int16$random", "func(min=Int16.min, max=Int16.max)->Int16"}, {"random", "Int16$random", "func(min=Int16.min, max=Int16.max -> Int16)"},
)}, )},
{"Int8", Type(IntType, .bits=TYPE_IBITS8), "Int8_t", "Int8$info", TypedArray(ns_entry_t, {"Int8", Type(IntType, .bits=TYPE_IBITS8), "Int8_t", "Int8$info", TypedArray(ns_entry_t,
{"abs", "abs", "func(i:Int8)->Int8"}, {"abs", "abs", "func(i:Int8 -> Int8)"},
{"bits", "Int8$bits", "func(x:Int8)->[Bool]"}, {"bits", "Int8$bits", "func(x:Int8 -> [Bool])"},
{"clamped", "Int8$clamped", "func(x,low,high:Int8)->Int8"}, {"clamped", "Int8$clamped", "func(x,low,high:Int8 -> Int8)"},
{"divided_by", "Int8$divided_by", "func(x,y:Int8)->Int8"}, {"divided_by", "Int8$divided_by", "func(x,y:Int8 -> Int8)"},
{"format", "Int8$format", "func(i:Int8, digits=0)->Text"}, {"format", "Int8$format", "func(i:Int8, digits=0 -> Text)"},
{"from_text", "Int8$from_text", "func(text:Text)->Int8?"}, {"from_text", "Int8$from_text", "func(text:Text -> Int8?)"},
{"hex", "Int8$hex", "func(i:Int8, digits=0, uppercase=yes, prefix=yes)->Text"}, {"hex", "Int8$hex", "func(i:Int8, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"max", "Int8$max", "Int8"}, {"max", "Int8$max", "Int8"},
{"min", "Int8$min", "Int8"}, {"min", "Int8$min", "Int8"},
{"modulo", "Int8$modulo", "func(x,y:Int8)->Int8"}, {"modulo", "Int8$modulo", "func(x,y:Int8 -> Int8)"},
{"modulo1", "Int8$modulo1", "func(x,y:Int8)->Int8"}, {"modulo1", "Int8$modulo1", "func(x,y:Int8 -> Int8)"},
{"octal", "Int8$octal", "func(i:Int8, digits=0, prefix=yes)->Text"}, {"octal", "Int8$octal", "func(i:Int8, digits=0, prefix=yes -> Text)"},
{"to", "Int8$to", "func(from:Int8,to:Int8)->Range"}, {"to", "Int8$to", "func(from:Int8,to:Int8 -> Range)"},
// Must be defined after min/max: // Must be defined after min/max:
{"random", "Int8$random", "func(min=Int8.min, max=Int8.max)->Int8"}, {"random", "Int8$random", "func(min=Int8.min, max=Int8.max -> Int8)"},
)}, )},
#define C(name) {#name, "M_"#name, "Num"} #define C(name) {#name, "M_"#name, "Num"}
#define F(name) {#name, #name, "func(n:Num)->Num"} #define F(name) {#name, #name, "func(n:Num -> Num)"}
#define F2(name) {#name, #name, "func(x,y:Num)->Num"} #define F2(name) {#name, #name, "func(x,y:Num -> Num)"}
{"Num", Type(NumType, .bits=TYPE_NBITS64), "Num_t", "Num$info", TypedArray(ns_entry_t, {"Num", Type(NumType, .bits=TYPE_NBITS64), "Num_t", "Num$info", TypedArray(ns_entry_t,
{"near", "Num$near", "func(x,y:Num, ratio=1e-9, min_epsilon=1e-9)->Bool"}, {"near", "Num$near", "func(x,y:Num, ratio=1e-9, min_epsilon=1e-9 -> Bool)"},
{"clamped", "Num$clamped", "func(x,low,high:Num)->Num"}, {"clamped", "Num$clamped", "func(x,low,high:Num -> Num)"},
{"format", "Num$format", "func(n:Num, precision=0)->Text"}, {"format", "Num$format", "func(n:Num, precision=0 -> Text)"},
{"scientific", "Num$scientific", "func(n:Num, precision=0)->Text"}, {"scientific", "Num$scientific", "func(n:Num,precision=0 -> Text)"},
{"nan", "Num$nan", "func(tag=\"\")->Num"}, {"nan", "Num$nan", "func(tag=\"\" -> Num)"},
{"isinf", "Num$isinf", "func(n:Num)->Bool"}, {"isinf", "Num$isinf", "func(n:Num -> Bool)"},
{"isfinite", "Num$isfinite", "func(n:Num)->Bool"}, {"isfinite", "Num$isfinite", "func(n:Num -> Bool)"},
{"isnan", "Num$isnan", "func(n:Num)->Bool"}, {"isnan", "Num$isnan", "func(n:Num -> Bool)"},
C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E), C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E),
C(PI), C(PI_4), C(SQRT2), C(SQRT1_2), C(PI), C(PI_4), C(SQRT2), C(SQRT1_2),
{"INF", "(Num_t)(INFINITY)", "Num"}, {"INF", "(Num_t)(INFINITY)", "Num"},
{"TAU", "(Num_t)(2.*M_PI)", "Num"}, {"TAU", "(Num_t)(2.*M_PI)", "Num"},
{"random", "Num$random", "func()->Num"}, {"random", "Num$random", "func(->Num)"},
{"mix", "Num$mix", "func(amount,x,y:Num)->Num"}, {"mix", "Num$mix", "func(amount,x,y:Num -> Num)"},
{"from_text", "Num$from_text", "func(text:Text)->Num?"}, {"from_text", "Num$from_text", "func(text:Text -> Num?)"},
{"abs", "fabs", "func(n:Num)->Num"}, {"abs", "fabs", "func(n:Num -> Num)"},
F(acos), F(acosh), F(asin), F(asinh), F(atan), F(atanh), F(cbrt), F(ceil), F(cos), F(cosh), F(erf), F(erfc), F(acos), F(acosh), F(asin), F(asinh), F(atan), F(atanh), F(cbrt), F(ceil), F(cos), F(cosh), F(erf), F(erfc),
F(exp), F(exp2), F(expm1), F(floor), F(j0), F(j1), F(log), F(log10), F(log1p), F(log2), F(logb), F(exp), F(exp2), F(expm1), F(floor), F(j0), F(j1), F(log), F(log10), F(log1p), F(log2), F(logb),
F(rint), F(round), F(significand), F(sin), F(sinh), F(sqrt), F(rint), F(round), F(significand), F(sin), F(sinh), F(sqrt),
@ -222,25 +222,25 @@ env_t *new_compilation_unit(CORD libname)
#undef F #undef F
#undef C #undef C
#define C(name) {#name, "(Num32_t)(M_"#name")", "Num32"} #define C(name) {#name, "(Num32_t)(M_"#name")", "Num32"}
#define F(name) {#name, #name"f", "func(n:Num32)->Num32"} #define F(name) {#name, #name"f", "func(n:Num32 -> Num32)"}
#define F2(name) {#name, #name"f", "func(x,y:Num32)->Num32"} #define F2(name) {#name, #name"f", "func(x,y:Num32 -> Num32)"}
{"Num32", Type(NumType, .bits=TYPE_NBITS32), "Num32_t", "Num32$info", TypedArray(ns_entry_t, {"Num32", Type(NumType, .bits=TYPE_NBITS32), "Num32_t", "Num32$info", TypedArray(ns_entry_t,
{"near", "Num32$near", "func(x,y:Num32, ratio=1e-9f32, min_epsilon=1e-9f32)->Bool"}, {"near", "Num32$near", "func(x,y:Num32, ratio=1e-9f32, min_epsilon=1e-9f32 -> Bool)"},
{"clamped", "Num32$clamped", "func(x,low,high:Num32)->Num32"}, {"clamped", "Num32$clamped", "func(x,low,high:Num32 -> Num32)"},
{"format", "Num32$format", "func(n:Num32, precision=0)->Text"}, {"format", "Num32$format", "func(n:Num32, precision=0 -> Text)"},
{"scientific", "Num32$scientific", "func(n:Num32, precision=0)->Text"}, {"scientific", "Num32$scientific", "func(n:Num32, precision=0 -> Text)"},
{"nan", "Num32$nan", "func(tag=\"\")->Num32"}, {"nan", "Num32$nan", "func(tag=\"\" -> Num32)"},
{"isinf", "Num32$isinf", "func(n:Num32)->Bool"}, {"isinf", "Num32$isinf", "func(n:Num32 -> Bool)"},
{"isfinite", "Num32$isfinite", "func(n:Num32)->Bool"}, {"isfinite", "Num32$isfinite", "func(n:Num32 -> Bool)"},
{"isnan", "Num32$isnan", "func(n:Num32)->Bool"}, {"isnan", "Num32$isnan", "func(n:Num32 -> Bool)"},
C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E), C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E),
C(PI), C(PI_4), C(SQRT2), C(SQRT1_2), C(PI), C(PI_4), C(SQRT2), C(SQRT1_2),
{"INF", "(Num32_t)(INFINITY)", "Num32"}, {"INF", "(Num32_t)(INFINITY)", "Num32"},
{"TAU", "(Num32_t)(2.f*M_PI)", "Num32"}, {"TAU", "(Num32_t)(2.f*M_PI)", "Num32"},
{"random", "Num32$random", "func()->Num32"}, {"random", "Num32$random", "func(->Num32)"},
{"mix", "Num32$mix", "func(amount,x,y:Num32)->Num32"}, {"mix", "Num32$mix", "func(amount,x,y:Num32 -> Num32)"},
{"from_text", "Num32$from_text", "func(text:Text)->Num32?"}, {"from_text", "Num32$from_text", "func(text:Text -> Num32?)"},
{"abs", "fabsf", "func(n:Num32)->Num32"}, {"abs", "fabsf", "func(n:Num32 -> Num32)"},
F(acos), F(acosh), F(asin), F(asinh), F(atan), F(atanh), F(cbrt), F(ceil), F(cos), F(cosh), F(erf), F(erfc), F(acos), F(acosh), F(asin), F(asinh), F(atan), F(atanh), F(cbrt), F(ceil), F(cos), F(cosh), F(erf), F(erfc),
F(exp), F(exp2), F(expm1), F(floor), F(j0), F(j1), F(log), F(log10), F(log1p), F(log2), F(logb), F(exp), F(exp2), F(expm1), F(floor), F(j0), F(j1), F(log), F(log10), F(log1p), F(log2), F(logb),
F(rint), F(round), F(significand), F(sin), F(sinh), F(sqrt), F(rint), F(round), F(significand), F(sin), F(sinh), F(sqrt),
@ -248,122 +248,122 @@ env_t *new_compilation_unit(CORD libname)
F2(atan2), F2(copysign), F2(fdim), F2(hypot), F2(nextafter), F2(pow), F2(remainder), F2(atan2), F2(copysign), F2(fdim), F2(hypot), F2(nextafter), F2(pow), F2(remainder),
)}, )},
{"CString", Type(CStringType), "char*", "CString$info", TypedArray(ns_entry_t, {"CString", Type(CStringType), "char*", "CString$info", TypedArray(ns_entry_t,
{"as_text", "CString$as_text_simple", "func(str:CString)->Text"}, {"as_text", "CString$as_text_simple", "func(str:CString -> Text)"},
)}, )},
#undef F2 #undef F2
#undef F #undef F
#undef C #undef C
{"Range", RANGE_TYPE, "Range_t", "Range", TypedArray(ns_entry_t, {"Range", RANGE_TYPE, "Range_t", "Range", TypedArray(ns_entry_t,
{"reversed", "Range$reversed", "func(range:Range)->Range"}, {"reversed", "Range$reversed", "func(range:Range -> Range)"},
{"by", "Range$by", "func(range:Range, step:Int)->Range"}, {"by", "Range$by", "func(range:Range, step:Int -> Range)"},
)}, )},
{"Pattern", Type(TextType, .lang="Pattern", .env=namespace_env(env, "Pattern")), "Pattern_t", "Pattern$info", TypedArray(ns_entry_t, {"Pattern", Type(TextType, .lang="Pattern", .env=namespace_env(env, "Pattern")), "Pattern_t", "Pattern$info", TypedArray(ns_entry_t,
{"escape_int", "Int$value_as_text", "func(i:Int)->Pattern"}, {"escape_int", "Int$value_as_text", "func(i:Int -> Pattern)"},
{"escape_text", "Pattern$escape_text", "func(text:Text)->Pattern"}, {"escape_text", "Pattern$escape_text", "func(text:Text -> Pattern)"},
)}, )},
{"DateTime", Type(DateTimeType), "DateTime_t", "DateTime", TypedArray(ns_entry_t, {"DateTime", Type(DateTimeType), "DateTime_t", "DateTime", TypedArray(ns_entry_t,
// Used as a default for functions below: // Used as a default for functions below:
{"now", "DateTime$now", "func()->DateTime"}, {"now", "DateTime$now", "func(->DateTime)"},
{"after", "DateTime$after", "func(dt:DateTime,seconds,minutes,hours=0.0,days,weeks,months,years=0,timezone=!Text)->DateTime"}, {"after", "DateTime$after", "func(dt:DateTime,seconds,minutes,hours=0.0,days,weeks,months,years=0,timezone=!Text -> DateTime)"},
{"date", "DateTime$date", "func(dt:DateTime,timezone=!Text)->Text"}, {"date", "DateTime$date", "func(dt:DateTime,timezone=!Text -> Text)"},
{"format", "DateTime$format", "func(dt:DateTime,format=\"%Y-%m-%dT%H:%M:%S%z\",timezone=!Text)->Text"}, {"format", "DateTime$format", "func(dt:DateTime,format=\"%Y-%m-%dT%H:%M:%S%z\",timezone=!Text -> Text)"},
{"from_unix_timestamp", "DateTime$from_unix_timestamp", "func(timestamp:Int64)->DateTime"}, {"from_unix_timestamp", "DateTime$from_unix_timestamp", "func(timestamp:Int64 -> DateTime)"},
{"get", "DateTime$get", "func(dt:DateTime,year,month,day,hour,minute,second,nanosecond,weekday=!&Int, timezone=!Text)"}, {"get", "DateTime$get", "func(dt:DateTime,year,month,day,hour,minute,second,nanosecond,weekday=!&Int,timezone=!Text)"},
{"get_local_timezone", "DateTime$get_local_timezone", "func()->Text"}, {"get_local_timezone", "DateTime$get_local_timezone", "func(->Text)"},
{"hours_till", "DateTime$hours_till", "func(now,then:DateTime)->Num"}, {"hours_till", "DateTime$hours_till", "func(now,then:DateTime -> Num)"},
{"minutes_till", "DateTime$minutes_till", "func(now,then:DateTime)->Num"}, {"minutes_till", "DateTime$minutes_till", "func(now,then:DateTime -> Num)"},
{"new", "DateTime$new", "func(year,month,day:Int,hour,minute=0,second=0.0,timezone=!Text)->DateTime"}, {"new", "DateTime$new", "func(year,month,day:Int,hour,minute=0,second=0.0,timezone=!Text -> DateTime)"},
{"parse", "DateTime$parse", "func(text:Text, format=\"%Y-%m-%dT%H:%M:%S%z\")->DateTime?"}, {"parse", "DateTime$parse", "func(text:Text, format=\"%Y-%m-%dT%H:%M:%S%z\" -> DateTime?)"},
{"relative", "DateTime$relative", "func(dt:DateTime,relative_to=DateTime.now(),timezone=!Text)->Text"}, {"relative", "DateTime$relative", "func(dt:DateTime,relative_to=DateTime.now(),timezone=!Text -> Text)"},
{"seconds_till", "DateTime$seconds_till", "func(now:DateTime,then:DateTime)->Num"}, {"seconds_till", "DateTime$seconds_till", "func(now:DateTime,then:DateTime -> Num)"},
{"set_local_timezone", "DateTime$set_local_timezone", "func(timezone=!Text)"}, {"set_local_timezone", "DateTime$set_local_timezone", "func(timezone=!Text)"},
{"time", "DateTime$time", "func(dt:DateTime,seconds=no,am_pm=yes,timezone=!Text)->Text"}, {"time", "DateTime$time", "func(dt:DateTime,seconds=no,am_pm=yes,timezone=!Text -> Text)"},
{"unix_timestamp", "DateTime$unix_timestamp", "func(dt:DateTime)->Int64"}, {"unix_timestamp", "DateTime$unix_timestamp", "func(dt:DateTime -> Int64)"},
)}, )},
{"Path", Type(TextType, .lang="Path", .env=namespace_env(env, "Path")), "Text_t", "Text$info", TypedArray(ns_entry_t, {"Path", Type(TextType, .lang="Path", .env=namespace_env(env, "Path")), "Text_t", "Text$info", TypedArray(ns_entry_t,
{"append", "Path$append", "func(path:Path, text:Text, permissions=0o644[32])"}, {"append", "Path$append", "func(path:Path, text:Text, permissions=0o644[32])"},
{"append_bytes", "Path$append_bytes", "func(path:Path, bytes:[Byte], permissions=0o644[32])"}, {"append_bytes", "Path$append_bytes", "func(path:Path, bytes:[Byte], permissions=0o644[32])"},
{"base_name", "Path$base_name", "func(path:Path)->Text"}, {"base_name", "Path$base_name", "func(path:Path -> Text)"},
{"by_line", "Path$by_line", "func(path:Path)->(func()->Text?)?"}, {"by_line", "Path$by_line", "func(path:Path -> func(->Text?)?)"},
{"children", "Path$children", "func(path:Path, include_hidden=no)->[Path]"}, {"children", "Path$children", "func(path:Path, include_hidden=no -> [Path])"},
{"create_directory", "Path$create_directory", "func(path:Path, permissions=0o755[32])"}, {"create_directory", "Path$create_directory", "func(path:Path, permissions=0o755[32])"},
{"escape_int", "Int$value_as_text", "func(i:Int)->Path"}, {"escape_int", "Int$value_as_text", "func(i:Int -> Path)"},
{"escape_path", "Path$escape_path", "func(path:Path)->Path"}, {"escape_path", "Path$escape_path", "func(path:Path -> Path)"},
{"escape_text", "Path$escape_text", "func(text:Text)->Path"}, {"escape_text", "Path$escape_text", "func(text:Text -> Path)"},
{"exists", "Path$exists", "func(path:Path)->Bool"}, {"exists", "Path$exists", "func(path:Path -> Bool)"},
{"extension", "Path$extension", "func(path:Path, full=yes)->Text"}, {"extension", "Path$extension", "func(path:Path, full=yes -> Text)"},
{"files", "Path$children", "func(path:Path, include_hidden=no)->[Path]"}, {"files", "Path$children", "func(path:Path, include_hidden=no -> [Path])"},
{"is_directory", "Path$is_directory", "func(path:Path, follow_symlinks=yes)->Bool"}, {"is_directory", "Path$is_directory", "func(path:Path, follow_symlinks=yes -> Bool)"},
{"is_file", "Path$is_file", "func(path:Path, follow_symlinks=yes)->Bool"}, {"is_file", "Path$is_file", "func(path:Path, follow_symlinks=yes -> Bool)"},
{"is_pipe", "Path$is_pipe", "func(path:Path, follow_symlinks=yes)->Bool"}, {"is_pipe", "Path$is_pipe", "func(path:Path, follow_symlinks=yes -> Bool)"},
{"is_socket", "Path$is_socket", "func(path:Path, follow_symlinks=yes)->Bool"}, {"is_socket", "Path$is_socket", "func(path:Path, follow_symlinks=yes -> Bool)"},
{"is_symlink", "Path$is_symlink", "func(path:Path)->Bool"}, {"is_symlink", "Path$is_symlink", "func(path:Path -> Bool)"},
{"parent", "Path$parent", "func(path:Path)->Path"}, {"parent", "Path$parent", "func(path:Path -> Path)"},
{"read", "Path$read", "func(path:Path)->Text?"}, {"read", "Path$read", "func(path:Path -> Text?)"},
{"read_bytes", "Path$read_bytes", "func(path:Path)->[Byte]?"}, {"read_bytes", "Path$read_bytes", "func(path:Path -> [Byte]?)"},
{"relative", "Path$relative", "func(path:Path, relative_to=(./))->Path"}, {"relative", "Path$relative", "func(path:Path, relative_to=(./) -> Path)"},
{"remove", "Path$remove", "func(path:Path, ignore_missing=no)"}, {"remove", "Path$remove", "func(path:Path, ignore_missing=no)"},
{"resolved", "Path$resolved", "func(path:Path, relative_to=(./))->Path"}, {"resolved", "Path$resolved", "func(path:Path, relative_to=(./) -> Path)"},
{"subdirectories", "Path$children", "func(path:Path, include_hidden=no)->[Path]"}, {"subdirectories", "Path$children", "func(path:Path, include_hidden=no -> [Path])"},
{"unique_directory", "Path$unique_directory", "func(path:Path)->Path"}, {"unique_directory", "Path$unique_directory", "func(path:Path -> Path)"},
{"write", "Path$write", "func(path:Path, text:Text, permissions=0o644[32])"}, {"write", "Path$write", "func(path:Path, text:Text, permissions=0o644[32])"},
{"write_bytes", "Path$write_bytes", "func(path:Path, bytes:[Byte], permissions=0o644[32])"}, {"write_bytes", "Path$write_bytes", "func(path:Path, bytes:[Byte], permissions=0o644[32])"},
{"write_unique", "Path$write_unique", "func(path:Path, text:Text)->Path"}, {"write_unique", "Path$write_unique", "func(path:Path, text:Text -> Path)"},
{"write_unique_bytes", "Path$write_unique_bytes", "func(path:Path, bytes:[Byte])->Path"}, {"write_unique_bytes", "Path$write_unique_bytes", "func(path:Path, bytes:[Byte] -> Path)"},
{"modified", "Path$modified", "func(path:Path, follow_symlinks=yes)->DateTime?"}, {"modified", "Path$modified", "func(path:Path, follow_symlinks=yes -> DateTime?)"},
{"accessed", "Path$accessed", "func(path:Path, follow_symlinks=yes)->DateTime?"}, {"accessed", "Path$accessed", "func(path:Path, follow_symlinks=yes -> DateTime?)"},
{"changed", "Path$changed", "func(path:Path, follow_symlinks=yes)->DateTime?"}, {"changed", "Path$changed", "func(path:Path, follow_symlinks=yes -> DateTime?)"},
// Text methods: // Text methods:
{"ends_with", "Text$ends_with", "func(path:Path, suffix:Text)->Bool"}, {"ends_with", "Text$ends_with", "func(path:Path, suffix:Text -> Bool)"},
{"has", "Text$has", "func(path:Path, pattern:Pattern)->Bool"}, {"has", "Text$has", "func(path:Path, pattern:Pattern -> Bool)"},
{"matches", "Text$matches", "func(path:Path, pattern:Pattern)->[Text]?"}, {"matches", "Text$matches", "func(path:Path, pattern:Pattern -> [Text]?)"},
{"replace", "Text$replace", "func(path:Path, pattern:Pattern, replacement:Text, backref=$/\\/, recursive=yes)->Path"}, {"replace", "Text$replace", "func(path:Path, pattern:Pattern, replacement:Text, backref=$/\\/, recursive=yes -> Path)"},
{"replace_all", "Text$replace_all", "func(path:Path, replacements:{Pattern:Text}, backref=$/\\/, recursive=yes)->Path"}, {"replace_all", "Text$replace_all", "func(path:Path, replacements:{Pattern:Text}, backref=$/\\/, recursive=yes -> Path)"},
{"starts_with", "Text$starts_with", "func(path:Path, prefix:Text)->Bool"}, {"starts_with", "Text$starts_with", "func(path:Path, prefix:Text -> Bool)"},
)}, )},
{"Shell", Type(TextType, .lang="Shell", .env=namespace_env(env, "Shell")), "Shell_t", "Shell$info", TypedArray(ns_entry_t, {"Shell", Type(TextType, .lang="Shell", .env=namespace_env(env, "Shell")), "Shell_t", "Shell$info", TypedArray(ns_entry_t,
{"by_line", "Shell$by_line", "func(command:Shell)->(func()->Text?)?"}, {"by_line", "Shell$by_line", "func(command:Shell -> func(->Text?)?)"},
{"escape_int", "Int$value_as_text", "func(i:Int)->Shell"}, {"escape_int", "Int$value_as_text", "func(i:Int -> Shell)"},
{"escape_text", "Shell$escape_text", "func(text:Text)->Shell"}, {"escape_text", "Shell$escape_text", "func(text:Text -> Shell)"},
{"escape_text_array", "Shell$escape_text_array", "func(texts:[Text])->Shell"}, {"escape_text_array", "Shell$escape_text_array", "func(texts:[Text] -> Shell)"},
{"run_bytes", "Shell$run", "func(command:Shell)->[Byte]?"}, {"run_bytes", "Shell$run", "func(command:Shell -> [Byte]?)"},
{"run", "Shell$run", "func(command:Shell)->Text?"}, {"run", "Shell$run", "func(command:Shell -> Text?)"},
)}, )},
{"Text", TEXT_TYPE, "Text_t", "Text$info", TypedArray(ns_entry_t, {"Text", TEXT_TYPE, "Text_t", "Text$info", TypedArray(ns_entry_t,
{"as_c_string", "Text$as_c_string", "func(text:Text)->CString"}, {"as_c_string", "Text$as_c_string", "func(text:Text -> CString)"},
{"codepoint_names", "Text$codepoint_names", "func(text:Text)->[Text]"}, {"codepoint_names", "Text$codepoint_names", "func(text:Text -> [Text])"},
{"ends_with", "Text$ends_with", "func(text,suffix:Text)->Bool"}, {"ends_with", "Text$ends_with", "func(text,suffix:Text -> Bool)"},
{"find", "Text$find", "func(text:Text, pattern:Pattern, start=1, length=!&Int64)->Int"}, {"find", "Text$find", "func(text:Text, pattern:Pattern, start=1, length=!&Int64 -> Int)"},
{"find_all", "Text$find_all", "func(text:Text, pattern:Pattern)->[Text]"}, {"find_all", "Text$find_all", "func(text:Text, pattern:Pattern -> [Text])"},
{"from_bytes", "Text$from_bytes", "func(bytes:[Byte])->Text"}, {"from_bytes", "Text$from_bytes", "func(bytes:[Byte] -> Text)"},
{"from_c_string", "Text$from_str", "func(str:CString)->Text"}, {"from_c_string", "Text$from_str", "func(str:CString -> Text)"},
{"from_codepoint_names", "Text$from_codepoint_names", "func(codepoint_names:[Text])->Text"}, {"from_codepoint_names", "Text$from_codepoint_names", "func(codepoint_names:[Text] -> Text)"},
{"from_codepoints", "Text$from_codepoints", "func(codepoints:[Int32])->Text"}, {"from_codepoints", "Text$from_codepoints", "func(codepoints:[Int32] -> Text)"},
{"without_escaping", "Path$cleanup", "func(text:Text)->Path"}, {"without_escaping", "Path$cleanup", "func(text:Text -> Path)"},
{"has", "Text$has", "func(text:Text, pattern:Pattern)->Bool"}, {"has", "Text$has", "func(text:Text, pattern:Pattern -> Bool)"},
{"join", "Text$join", "func(glue:Text, pieces:[Text])->Text"}, {"join", "Text$join", "func(glue:Text, pieces:[Text] -> Text)"},
{"lines", "Text$lines", "func(text:Text)->[Text]"}, {"lines", "Text$lines", "func(text:Text -> [Text])"},
{"lower", "Text$lower", "func(text:Text)->Text"}, {"lower", "Text$lower", "func(text:Text -> Text)"},
{"map", "Text$map", "func(text:Text, pattern:Pattern, fn:func(text:Text)->Text)->Text"}, {"map", "Text$map", "func(text:Text, pattern:Pattern, fn:func(text:Text -> Text) -> Text)"},
{"matches", "Text$matches", "func(text:Text, pattern:Pattern)->[Text]?"}, {"matches", "Text$matches", "func(text:Text, pattern:Pattern -> [Text]?)"},
{"quoted", "Text$quoted", "func(text:Text, color=no)->Text"}, {"quoted", "Text$quoted", "func(text:Text, color=no -> Text)"},
{"repeat", "Text$repeat", "func(text:Text, count:Int)->Text"}, {"repeat", "Text$repeat", "func(text:Text, count:Int -> Text)"},
{"replace", "Text$replace", "func(text:Text, pattern:Pattern, replacement:Text, backref=$/\\/, recursive=yes)->Text"}, {"replace", "Text$replace", "func(text:Text, pattern:Pattern, replacement:Text, backref=$/\\/, recursive=yes -> Text)"},
{"replace_all", "Text$replace_all", "func(text:Text, replacements:{Pattern:Text}, backref=$/\\/, recursive=yes)->Text"}, {"replace_all", "Text$replace_all", "func(text:Text, replacements:{Pattern:Text}, backref=$/\\/, recursive=yes -> Text)"},
{"slice", "Text$slice", "func(text:Text, from=1, to=-1)->Text"}, {"slice", "Text$slice", "func(text:Text, from=1, to=-1 -> Text)"},
{"split", "Text$split", "func(text:Text, pattern=$Pattern'')->[Text]"}, {"split", "Text$split", "func(text:Text, pattern=$Pattern'' -> [Text])"},
{"starts_with", "Text$starts_with", "func(text,prefix:Text)->Bool"}, {"starts_with", "Text$starts_with", "func(text,prefix:Text -> Bool)"},
{"title", "Text$title", "func(text:Text)->Text"}, {"title", "Text$title", "func(text:Text -> Text)"},
{"trim", "Text$trim", "func(text:Text, pattern=$/{whitespace}/, trim_left=yes, trim_right=yes)->Text"}, {"trim", "Text$trim", "func(text:Text, pattern=$/{whitespace}/, trim_left=yes, trim_right=yes -> Text)"},
{"upper", "Text$upper", "func(text:Text)->Text"}, {"upper", "Text$upper", "func(text:Text -> Text)"},
{"utf32_codepoints", "Text$utf32_codepoints", "func(text:Text)->[Int32]"}, {"utf32_codepoints", "Text$utf32_codepoints", "func(text:Text -> [Int32])"},
{"utf8_bytes", "Text$utf8_bytes", "func(text:Text)->[Byte]"}, {"utf8_bytes", "Text$utf8_bytes", "func(text:Text -> [Byte])"},
)}, )},
{"Thread", THREAD_TYPE, "Thread_t", "Thread", TypedArray(ns_entry_t, {"Thread", THREAD_TYPE, "Thread_t", "Thread", TypedArray(ns_entry_t,
{"new", "Thread$new", "func(fn:func())->Thread"}, {"new", "Thread$new", "func(fn:func() -> Thread)"},
{"cancel", "Thread$cancel", "func(thread:Thread)"}, {"cancel", "Thread$cancel", "func(thread:Thread)"},
{"join", "Thread$join", "func(thread:Thread)"}, {"join", "Thread$join", "func(thread:Thread)"},
{"detach", "Thread$detach", "func(thread:Thread)"}, {"detach", "Thread$detach", "func(thread:Thread)"},

View File

@ -6,7 +6,7 @@ use <raymath.h>
use ./world.tm use ./world.tm
func main(map=(./map.txt)): func main(map=(./map.txt)):
extern InitWindow:func(w:Int32, h:Int32, title:CString)->Void extern InitWindow:func(w:Int32, h:Int32, title:CString)
InitWindow(1600, 900, "raylib [core] example - 2d camera") InitWindow(1600, 900, "raylib [core] example - 2d camera")
map_contents := map:read() or exit("Could not find the game map: $map") map_contents := map:read() or exit("Could not find the game map: $map")
@ -16,10 +16,10 @@ func main(map=(./map.txt)):
extern SetTargetFPS:func(fps:Int32) extern SetTargetFPS:func(fps:Int32)
SetTargetFPS(60) SetTargetFPS(60)
extern WindowShouldClose:func()->Bool extern WindowShouldClose:func(->Bool)
while not WindowShouldClose(): while not WindowShouldClose():
extern GetFrameTime:func()->Num32 extern GetFrameTime:func(->Num32)
dt := GetFrameTime() dt := GetFrameTime()
World.CURRENT:update(Num(dt)) World.CURRENT:update(Num(dt))

View File

@ -6,7 +6,7 @@ use ./color.tm
use ./box.tm use ./box.tm
# Return a displacement relative to `a` that will push it out of `b` # Return a displacement relative to `a` that will push it out of `b`
func solve_overlap(a_pos:Vec2, a_size:Vec2, b_pos:Vec2, b_size:Vec2)->Vec2: func solve_overlap(a_pos:Vec2, a_size:Vec2, b_pos:Vec2, b_size:Vec2 -> Vec2):
a_left := a_pos.x a_left := a_pos.x
a_right := a_pos.x + a_size.x a_right := a_pos.x + a_size.x
a_top := a_pos.y a_top := a_pos.y

View File

@ -7,7 +7,7 @@ struct HTTPResponse(code:Int, body:Text)
enum _Method(GET, POST, PUT, PATCH, DELETE) enum _Method(GET, POST, PUT, PATCH, DELETE)
func _send(method:_Method, url:Text, data:Text?, headers=[:Text])->HTTPResponse: func _send(method:_Method, url:Text, data:Text?, headers=[:Text] -> HTTPResponse):
chunks := @[:Text] chunks := @[:Text]
save_chunk := func(chunk:CString, size:Int64, n:Int64): save_chunk := func(chunk:CString, size:Int64, n:Int64):
chunks:insert(inline C:Text { chunks:insert(inline C:Text {
@ -69,16 +69,16 @@ func _send(method:_Method, url:Text, data:Text?, headers=[:Text])->HTTPResponse:
} }
return HTTPResponse(code, "":join(chunks)) return HTTPResponse(code, "":join(chunks))
func get(url:Text, headers=[:Text])->HTTPResponse: func get(url:Text, headers=[:Text] -> HTTPResponse):
return _send(GET, url, !Text, headers) return _send(GET, url, !Text, headers)
func post(url:Text, data="", headers=["Content-Type: application/json", "Accept: application/json"])->HTTPResponse: func post(url:Text, data="", headers=["Content-Type: application/json", "Accept: application/json"] -> HTTPResponse):
return _send(POST, url, data, headers) return _send(POST, url, data, headers)
func put(url:Text, data="", headers=["Content-Type: application/json", "Accept: application/json"])->HTTPResponse: func put(url:Text, data="", headers=["Content-Type: application/json", "Accept: application/json"] -> HTTPResponse):
return _send(PUT, url, data, headers) return _send(PUT, url, data, headers)
func delete(url:Text, data=!Text, headers=["Content-Type: application/json", "Accept: application/json"])->HTTPResponse: func delete(url:Text, data=!Text, headers=["Content-Type: application/json", "Accept: application/json"] -> HTTPResponse):
return _send(DELETE, url, data, headers) return _send(DELETE, url, data, headers)
func main(): func main():

View File

@ -6,7 +6,7 @@ _HELP := "
$_USAGE $_USAGE
" "
func parse_ini(path:Path)->{Text:{Text:Text}}: func parse_ini(path:Path -> {Text:{Text:Text}}):
text := path:read() or exit("Could not read INI file: $\[31;1]$(path.text_content)$\[]") text := path:read() or exit("Could not read INI file: $\[31;1]$(path.text_content)$\[]")
sections := {:Text:@{Text:Text}} sections := {:Text:@{Text:Text}}
current_section := @{:Text:Text} current_section := @{:Text:Text}

View File

@ -211,12 +211,12 @@ func main():
# Functions must be declared at the top level of a file and must specify the # Functions must be declared at the top level of a file and must specify the
# types of all of their arguments and return value (if any): # types of all of their arguments and return value (if any):
func add(x:Int, y:Int)->Int: func add(x:Int, y:Int -> Int):
return x + y return x + y
# Default values for arguments can be provided in place of a type (the type is # Default values for arguments can be provided in place of a type (the type is
# inferred from the default value): # inferred from the default value):
func show_both(first:Int, second=0)->Text: func show_both(first:Int, second=0 -> Text):
return "first=$first second=$second" return "first=$first second=$second"
func demo_keyword_args(): func demo_keyword_args():
@ -241,7 +241,7 @@ func takes_many_types(
table_of_text_to_bools:{Text:Bool}, table_of_text_to_bools:{Text:Bool},
pointer_to_mutable_array_of_ints:@[Int], pointer_to_mutable_array_of_ints:@[Int],
optional_int:Int?, optional_int:Int?,
function_from_int_to_text:func(x:Int)->Text, function_from_int_to_text:func(x:Int -> Text),
): ):
pass pass
@ -259,7 +259,7 @@ struct Person(name:Text, age:Int):
self.age += amount self.age += amount
# Methods don't have to take a Person as their first argument: # Methods don't have to take a Person as their first argument:
func get_cool_name()->Text: func get_cool_name(->Text):
return "Blade" return "Blade"
func demo_structs(): func demo_structs():
@ -304,7 +304,7 @@ enum Shape(
): ):
# Just like with structs, you define methods and constants inside a level # Just like with structs, you define methods and constants inside a level
# of indentation: # of indentation:
func get_area(self:Shape)->Num: func get_area(self:Shape->Num):
# In order to work with an enum, it's most often handy to use a 'when' # In order to work with an enum, it's most often handy to use a 'when'
# statement to get the internal values: # statement to get the internal values:
when self is Point: when self is Point:

View File

@ -5,7 +5,7 @@ timestamp_format := CString("%F %T")
logfiles := {:Path} logfiles := {:Path}
func _timestamp()->Text: func _timestamp(->Text):
c_str := inline C:CString { c_str := inline C:CString {
char *str = GC_MALLOC_ATOMIC(20); char *str = GC_MALLOC_ATOMIC(20);
time_t t; time(&t); time_t t; time(&t);

View File

@ -9,7 +9,7 @@ _HELP := "
enum Dependency(File(path:Path), Module(name:Text)) enum Dependency(File(path:Path), Module(name:Text))
func _get_file_dependencies(file:Path)->{Dependency}: func _get_file_dependencies(file:Path -> {Dependency}):
if not file:is_file(): if not file:is_file():
!! Could not read file: $file !! Could not read file: $file
return {:Dependency} return {:Dependency}
@ -55,12 +55,12 @@ func _build_dependency_graph(dep:Dependency, dependencies:&{Dependency:{Dependen
for dep2 in dep_deps: for dep2 in dep_deps:
_build_dependency_graph(dep2, dependencies) _build_dependency_graph(dep2, dependencies)
func get_dependency_graph(dep:Dependency)->{Dependency:{Dependency}}: func get_dependency_graph(dep:Dependency -> {Dependency:{Dependency}}):
graph := {:Dependency:{Dependency}} graph := {:Dependency:{Dependency}}
_build_dependency_graph(dep, &graph) _build_dependency_graph(dep, &graph)
return graph return graph
func _printable_name(dep:Dependency)->Text: func _printable_name(dep:Dependency -> Text):
when dep is Module(module): when dep is Module(module):
return "$(\x1b)[34;1m$module$(\x1b)[m" return "$(\x1b)[34;1m$module$(\x1b)[m"
is File(f): is File(f):

View File

@ -2,32 +2,32 @@
struct Vec2(x,y:Num): struct Vec2(x,y:Num):
ZERO := Vec2(0, 0) ZERO := Vec2(0, 0)
func plus(a,b:Vec2; inline)->Vec2: func plus(a,b:Vec2->Vec2; inline):
return Vec2(a.x+b.x, a.y+b.y) return Vec2(a.x+b.x, a.y+b.y)
func minus(a,b:Vec2; inline)->Vec2: func minus(a,b:Vec2->Vec2; inline):
return Vec2(a.x-b.x, a.y-b.y) return Vec2(a.x-b.x, a.y-b.y)
func times(a,b:Vec2; inline)->Vec2: func times(a,b:Vec2->Vec2; inline):
return Vec2(a.x*b.x, a.y*b.y) return Vec2(a.x*b.x, a.y*b.y)
func dot(a,b:Vec2; inline)->Num: func dot(a,b:Vec2->Num; inline):
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)
func cross(a,b:Vec2; inline)->Num: func cross(a,b:Vec2->Num; inline):
return a.x*b.y - a.y*b.x return a.x*b.y - a.y*b.x
func scaled_by(v:Vec2, k:Num; inline)->Vec2: func scaled_by(v:Vec2, k:Num->Vec2; inline):
return Vec2(v.x*k, v.y*k) return Vec2(v.x*k, v.y*k)
func divided_by(v:Vec2, divisor:Num; inline)->Vec2: func divided_by(v:Vec2, divisor:Num->Vec2; inline):
return Vec2(v.x/divisor, v.y/divisor) return Vec2(v.x/divisor, v.y/divisor)
func length(v:Vec2; inline)->Num: func length(v:Vec2->Num; inline):
return (v.x*v.x + v.y*v.y):sqrt() return (v.x*v.x + v.y*v.y):sqrt()
func dist(a,b:Vec2; inline)->Num: func dist(a,b:Vec2->Num; inline):
return a:minus(b):length() return a:minus(b):length()
func angle(v:Vec2; inline)->Num: func angle(v:Vec2->Num; inline):
return Num.atan2(v.y, v.x) return Num.atan2(v.y, v.x)
func norm(v:Vec2; inline)->Vec2: func norm(v:Vec2->Vec2; inline):
if v.x == 0 and v.y == 0: if v.x == 0 and v.y == 0:
return v return v
len := v:length() len := v:length()
return Vec2(v.x/len, v.y/len) return Vec2(v.x/len, v.y/len)
func mix(a,b:Vec2, amount:Num)->Vec2: func mix(a,b:Vec2, amount:Num -> Vec2):
return Vec2( return Vec2(
amount:mix(a.x, b.x), amount:mix(a.x, b.x),
amount:mix(a.y, b.y), amount:mix(a.y, b.y),
@ -35,30 +35,30 @@ struct Vec2(x,y:Num):
struct Vec3(x,y,z:Num): struct Vec3(x,y,z:Num):
ZERO := Vec3(0, 0, 0) ZERO := Vec3(0, 0, 0)
func plus(a,b:Vec3; inline)->Vec3: func plus(a,b:Vec3->Vec3; inline):
return Vec3(a.x+b.x, a.y+b.y, a.z+b.z) return Vec3(a.x+b.x, a.y+b.y, a.z+b.z)
func minus(a,b:Vec3; inline)->Vec3: func minus(a,b:Vec3->Vec3; inline):
return Vec3(a.x-b.x, a.y-b.y, a.z-b.z) return Vec3(a.x-b.x, a.y-b.y, a.z-b.z)
func times(a,b:Vec3; inline)->Vec3: func times(a,b:Vec3->Vec3; inline):
return Vec3(a.x*b.x, a.y*b.y, a.z*b.z) return Vec3(a.x*b.x, a.y*b.y, a.z*b.z)
func dot(a,b:Vec3; inline)->Num: func dot(a,b:Vec3->Num; inline):
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z) return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z)
func cross(a,b:Vec3; inline)->Vec3: func cross(a,b:Vec3->Vec3; inline):
return Vec3(a.y*b.z - a.z-b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x) return Vec3(a.y*b.z - a.z-b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x)
func scaled_by(v:Vec3, k:Num; inline)->Vec3: func scaled_by(v:Vec3, k:Num->Vec3; inline):
return Vec3(v.x*k, v.y*k, v.z*k) return Vec3(v.x*k, v.y*k, v.z*k)
func divided_by(v:Vec3, divisor:Num; inline)->Vec3: func divided_by(v:Vec3, divisor:Num->Vec3; inline):
return Vec3(v.x/divisor, v.y/divisor, v.z/divisor) return Vec3(v.x/divisor, v.y/divisor, v.z/divisor)
func length(v:Vec3; inline)->Num: func length(v:Vec3->Num; inline):
return (v.x*v.x + v.y*v.y + v.z*v.z):sqrt() return (v.x*v.x + v.y*v.y + v.z*v.z):sqrt()
func dist(a,b:Vec3; inline)->Num: func dist(a,b:Vec3->Num; inline):
return a:minus(b):length() return a:minus(b):length()
func norm(v:Vec3; inline)->Vec3: func norm(v:Vec3->Vec3; inline):
if v.x == 0 and v.y == 0 and v.z == 0: if v.x == 0 and v.y == 0 and v.z == 0:
return v return v
len := v:length() len := v:length()
return Vec3(v.x/len, v.y/len, v.z/len) return Vec3(v.x/len, v.y/len, v.z/len)
func mix(a,b:Vec3, amount:Num)->Vec3: func mix(a,b:Vec3, amount:Num -> Vec3):
return Vec3( return Vec3(
amount:mix(a.x, b.x), amount:mix(a.x, b.x),
amount:mix(a.y, b.y), amount:mix(a.y, b.y),
@ -68,46 +68,46 @@ struct Vec3(x,y,z:Num):
struct IVec2(x,y:Int): struct IVec2(x,y:Int):
ZERO := IVec2(0, 0) ZERO := IVec2(0, 0)
func plus(a,b:IVec2; inline)->IVec2: func plus(a,b:IVec2->IVec2; inline):
return IVec2(a.x+b.x, a.y+b.y) return IVec2(a.x+b.x, a.y+b.y)
func minus(a,b:IVec2; inline)->IVec2: func minus(a,b:IVec2->IVec2; inline):
return IVec2(a.x-b.x, a.y-b.y) return IVec2(a.x-b.x, a.y-b.y)
func times(a,b:IVec2; inline)->IVec2: func times(a,b:IVec2->IVec2; inline):
return IVec2(a.x*b.x, a.y*b.y) return IVec2(a.x*b.x, a.y*b.y)
func dot(a,b:IVec2; inline)->Int: func dot(a,b:IVec2->Int; inline):
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)
func cross(a,b:IVec2; inline)->Int: func cross(a,b:IVec2->Int; inline):
return a.x*b.y - a.y*b.x return a.x*b.y - a.y*b.x
func scaled_by(v:IVec2, k:Int; inline)->IVec2: func scaled_by(v:IVec2, k:Int->IVec2; inline):
return IVec2(v.x*k, v.y*k) return IVec2(v.x*k, v.y*k)
func divided_by(v:IVec2, divisor:Int; inline)->IVec2: func divided_by(v:IVec2, divisor:Int->IVec2; inline):
return IVec2(v.x/divisor, v.y/divisor) return IVec2(v.x/divisor, v.y/divisor)
func length(v:IVec2; inline)->Num: func length(v:IVec2->Num; inline):
return Num.sqrt(v.x*v.x + v.y*v.y) return Num.sqrt(v.x*v.x + v.y*v.y)
func dist(a,b:IVec2; inline)->Num: func dist(a,b:IVec2->Num; inline):
return a:minus(b):length() return a:minus(b):length()
func angle(v:IVec2; inline)->Num: func angle(v:IVec2->Num; inline):
return Num.atan2(v.y, v.x) return Num.atan2(v.y, v.x)
struct IVec3(x,y,z:Int): struct IVec3(x,y,z:Int):
ZERO := IVec3(0, 0, 0) ZERO := IVec3(0, 0, 0)
func plus(a,b:IVec3; inline)->IVec3: func plus(a,b:IVec3->IVec3; inline):
return IVec3(a.x+b.x, a.y+b.y, a.z+b.z) return IVec3(a.x+b.x, a.y+b.y, a.z+b.z)
func minus(a,b:IVec3; inline)->IVec3: func minus(a,b:IVec3->IVec3; inline):
return IVec3(a.x-b.x, a.y-b.y, a.z-b.z) return IVec3(a.x-b.x, a.y-b.y, a.z-b.z)
func times(a,b:IVec3; inline)->IVec3: func times(a,b:IVec3->IVec3; inline):
return IVec3(a.x*b.x, a.y*b.y, a.z*b.z) return IVec3(a.x*b.x, a.y*b.y, a.z*b.z)
func dot(a,b:IVec3; inline)->Int: func dot(a,b:IVec3->Int; inline):
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z) return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z)
func cross(a,b:IVec3; inline)->IVec3: func cross(a,b:IVec3->IVec3; inline):
return IVec3(a.y*b.z - a.z-b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x) return IVec3(a.y*b.z - a.z-b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x)
func scaled_by(v:IVec3, k:Int; inline)->IVec3: func scaled_by(v:IVec3, k:Int->IVec3; inline):
return IVec3(v.x*k, v.y*k, v.z*k) return IVec3(v.x*k, v.y*k, v.z*k)
func divided_by(v:IVec3, divisor:Int; inline)->IVec3: func divided_by(v:IVec3, divisor:Int->IVec3; inline):
return IVec3(v.x/divisor, v.y/divisor, v.z/divisor) return IVec3(v.x/divisor, v.y/divisor, v.z/divisor)
func length(v:IVec3; inline)->Num: func length(v:IVec3->Num; inline):
return Num.sqrt(v.x*v.x + v.y*v.y + v.z*v.z) return Num.sqrt(v.x*v.x + v.y*v.y + v.z*v.z)
func dist(a,b:IVec3; inline)->Num: func dist(a,b:IVec3->Num; inline):
return a:minus(b):length() return a:minus(b):length()
func main(): func main():

View File

@ -13,7 +13,7 @@ HELP := "
UNICODE_HYPHEN := \{hyphen} UNICODE_HYPHEN := \{hyphen}
func unwrap(text:Text, preserve_paragraphs=yes, hyphen=UNICODE_HYPHEN)->Text: func unwrap(text:Text, preserve_paragraphs=yes, hyphen=UNICODE_HYPHEN -> Text):
if preserve_paragraphs: if preserve_paragraphs:
paragraphs := text:split($/{2+ nl}/) paragraphs := text:split($/{2+ nl}/)
if paragraphs.length > 1: if paragraphs.length > 1:
@ -21,7 +21,7 @@ func unwrap(text:Text, preserve_paragraphs=yes, hyphen=UNICODE_HYPHEN)->Text:
return text:replace($/$(hyphen)$(\n)/, "") return text:replace($/$(hyphen)$(\n)/, "")
func wrap(text:Text, width:Int, min_split=3, hyphen="-")->Text: func wrap(text:Text, width:Int, min_split=3, hyphen="-" -> Text):
if width <= 0: if width <= 0:
fail("Width must be a positive integer, not $width") fail("Width must be a positive integer, not $width")
@ -71,7 +71,7 @@ func wrap(text:Text, width:Int, min_split=3, hyphen="-")->Text:
return \n:join(lines) return \n:join(lines)
func _can_fit_word(line:Text, letters:[Text], width:Int; inline)->Bool: func _can_fit_word(line:Text, letters:[Text], width:Int -> Bool; inline):
if line == "": if line == "":
return letters.length <= width return letters.length <= width
else: else:

14
parse.c
View File

@ -602,9 +602,9 @@ type_ast_t *parse_func_type(parse_ctx_t *ctx, const char *pos) {
spaces(&pos); spaces(&pos);
if (!match(&pos, "(")) return NULL; if (!match(&pos, "(")) return NULL;
arg_ast_t *args = parse_args(ctx, &pos); arg_ast_t *args = parse_args(ctx, &pos);
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function type");
spaces(&pos); spaces(&pos);
type_ast_t *ret = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL; type_ast_t *ret = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL;
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function type");
return NewTypeAST(ctx->file, start, pos, FunctionTypeAST, .args=args, .ret=ret); return NewTypeAST(ctx->file, start, pos, FunctionTypeAST, .args=args, .ret=ret);
} }
@ -691,6 +691,7 @@ type_ast_t *parse_non_optional_type(parse_ctx_t *ctx, const char *pos) {
type_ast_t *parse_type(parse_ctx_t *ctx, const char *pos) { type_ast_t *parse_type(parse_ctx_t *ctx, const char *pos) {
const char *start = pos; const char *start = pos;
type_ast_t *type = parse_non_optional_type(ctx, pos); type_ast_t *type = parse_non_optional_type(ctx, pos);
if (!type) return NULL;
pos = type->end; pos = type->end;
spaces(&pos); spaces(&pos);
if (match(&pos, "?")) if (match(&pos, "?"))
@ -1548,10 +1549,12 @@ PARSER(parse_lambda) {
return NULL; return NULL;
arg_ast_t *args = parse_args(ctx, &pos); arg_ast_t *args = parse_args(ctx, &pos);
spaces(&pos); spaces(&pos);
type_ast_t *ret = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL;
spaces(&pos);
expect_closing(ctx, &pos, ")", "I was expecting a ')' to finish this anonymous function's arguments"); expect_closing(ctx, &pos, ")", "I was expecting a ')' to finish this anonymous function's arguments");
ast_t *body = optional(ctx, &pos, parse_block); ast_t *body = optional(ctx, &pos, parse_block);
if (!body) body = NewAST(ctx->file, pos, pos, Block, .statements=NULL); if (!body) body = NewAST(ctx->file, pos, pos, Block, .statements=NULL);
return NewAST(ctx->file, start, pos, Lambda, .id=ctx->next_lambda_id++, .args=args, .body=body); return NewAST(ctx->file, start, pos, Lambda, .id=ctx->next_lambda_id++, .args=args, .ret_type=ret, .body=body);
} }
PARSER(parse_null) { PARSER(parse_null) {
@ -2242,6 +2245,8 @@ PARSER(parse_func_def) {
if (!match(&pos, "(")) return NULL; if (!match(&pos, "(")) return NULL;
arg_ast_t *args = parse_args(ctx, &pos); arg_ast_t *args = parse_args(ctx, &pos);
spaces(&pos);
type_ast_t *ret_type = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL;
whitespace(&pos); whitespace(&pos);
bool is_inline = false; bool is_inline = false;
ast_t *cache_ast = NULL; ast_t *cache_ast = NULL;
@ -2261,11 +2266,6 @@ PARSER(parse_func_def) {
} }
expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function definition"); expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function definition");
type_ast_t *ret_type = NULL;
spaces(&pos);
if (match(&pos, "->"))
ret_type = optional(ctx, &pos, parse_type);
ast_t *body = expect(ctx, start, &pos, parse_block, ast_t *body = expect(ctx, start, &pos, parse_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,

View File

@ -1,10 +1,10 @@
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:

View File

@ -76,7 +76,7 @@ func defer_func(return_early=no):
say("Finished defer_func") say("Finished defer_func")
func make_counter()->func()->Int: func make_counter(->func(->Int)):
i := 1 i := 1
return func(): return func():
defer: i += 1 defer: i += 1

View File

@ -1,6 +1,6 @@
enum Foo(Zero, One(x:Int), Two(x:Int, y:Int), Three(x:Int, y:Text, z:Bool), Four(x,y,z,w:Int), Last(t:Text)) enum Foo(Zero, One(x:Int), Two(x:Int, y:Int), Three(x:Int, y:Text, z:Bool), Four(x,y,z,w:Int), Last(t:Text))
func choose_text(f:Foo)->Text: func choose_text(f:Foo->Text):
>> f >> f
when f is Zero: when f is Zero:
return "Zero" return "Zero"

View File

@ -1,4 +1,4 @@
extern sqrt:func(n:Num)->Num extern sqrt:func(n:Num->Num)
func main(): func main():
>> sqrt(4) >> sqrt(4)

View File

@ -1,5 +1,5 @@
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,"
@ -7,7 +7,7 @@ func all_nums(nums:[Int])->Text:
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,"
@ -15,14 +15,14 @@ func labeled_nums(nums:[Int])->Text:
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,"

View File

@ -1,7 +1,7 @@
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->@Int; cached):
return @x return @x
func main(): func main():

View File

@ -1,10 +1,10 @@
vectors := use ../examples/vectors/vectors.tm vectors := use ../examples/vectors/vectors.tm
use ./use_import.tm use ./use_import.tm
func returns_vec()->vectors.Vec2: func returns_vec(->vectors.Vec2):
return vectors.Vec2(1, 2) return vectors.Vec2(1, 2)
func returns_imported_type()->ImportedType: func returns_imported_type(->ImportedType):
return get_value() # Imported from ./use_import.tm return get_value() # Imported from ./use_import.tm
func main(): func main():

View File

@ -1,14 +1,14 @@
struct Pair(x:Text, y:Text) struct Pair(x:Text, y:Text)
func pairwise(strs:[Text])->func()->Pair?: func pairwise(strs:[Text] -> func(->Pair?)):
i := 1 i := 1
return func(): return func():
if i + 1 > strs.length: return !Pair if i + 1 > strs.length: return !Pair
i += 1 i += 1
return Pair(strs[i-1], strs[i])? return Pair(strs[i-1], strs[i])?
func range(first:Int, last:Int)->func()->Int?: func range(first:Int, last:Int -> func(->Int?)):
i := first i := first
return func(): return func():
if i > last: if i > last:

View File

@ -1,10 +1,10 @@
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():

View File

@ -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_all({ t = t:replace_all({
$/&/: "&amp;", $/&/: "&amp;",
$/</: "&lt;", $/</: "&lt;",
@ -11,10 +11,10 @@ lang HTML:
return HTML.without_escaping(t) return HTML.without_escaping(t)
func escape_int(i:Int)->HTML: func escape_int(i:Int->HTML):
return HTML.without_escaping("$i") return HTML.without_escaping("$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():

View File

@ -1,47 +1,47 @@
struct Vec2(x,y:Int): struct Vec2(x,y:Int):
func plus(a,b:Vec2; inline)->Vec2: func plus(a,b:Vec2 -> Vec2; inline):
return Vec2(a.x+b.x, a.y+b.y) return Vec2(a.x+b.x, a.y+b.y)
func minus(a,b:Vec2; inline)->Vec2: func minus(a,b:Vec2 -> Vec2; inline):
return Vec2(a.x-b.x, a.y-b.y) return Vec2(a.x-b.x, a.y-b.y)
func dot(a,b:Vec2; inline)->Int: func dot(a,b:Vec2 -> Int; inline):
return a.x*b.x + a.y*b.y return a.x*b.x + a.y*b.y
func scaled_by(a:Vec2, k:Int; inline)->Vec2: func scaled_by(a:Vec2, k:Int -> Vec2; inline):
return Vec2(a.x*k, a.y*k) return Vec2(a.x*k, a.y*k)
func times(a,b:Vec2; inline)->Vec2: func times(a,b:Vec2 -> Vec2; inline):
return Vec2(a.x*b.x, a.y*b.y) return Vec2(a.x*b.x, a.y*b.y)
func divided_by(a:Vec2, k:Int; inline)->Vec2: func divided_by(a:Vec2, k:Int -> Vec2; inline):
return Vec2(a.x/k, a.y/k) return Vec2(a.x/k, a.y/k)
func negative(v:Vec2; inline)->Vec2: func negative(v:Vec2 -> Vec2; inline):
return Vec2(-v.x, -v.y) return Vec2(-v.x, -v.y)
func negated(v:Vec2; inline)->Vec2: func negated(v:Vec2 -> Vec2; inline):
return Vec2(not v.x, not v.y) return Vec2(not v.x, not v.y)
func bit_and(a,b:Vec2; inline)->Vec2: func bit_and(a,b:Vec2 -> Vec2; inline):
return Vec2(a.x and b.x, a.y and b.y) return Vec2(a.x and b.x, a.y and b.y)
func bit_or(a,b:Vec2; inline)->Vec2: func bit_or(a,b:Vec2 -> Vec2; inline):
return Vec2(a.x or b.x, a.y or b.y) return Vec2(a.x or b.x, a.y or b.y)
func bit_xor(a,b:Vec2; inline)->Vec2: func bit_xor(a,b:Vec2 -> Vec2; inline):
return Vec2(a.x xor b.x, a.y xor b.y) return Vec2(a.x xor b.x, a.y xor b.y)
func left_shifted(v:Vec2, bits:Int; inline)->Vec2: func left_shifted(v:Vec2, bits:Int -> Vec2; inline):
return Vec2(v.x >> bits, v.y >> bits) return Vec2(v.x >> bits, v.y >> bits)
func right_shifted(v:Vec2, bits:Int; inline)->Vec2: func right_shifted(v:Vec2, bits:Int -> Vec2; inline):
return Vec2(v.x << bits, v.y << bits) return Vec2(v.x << bits, v.y << bits)
func modulo(v:Vec2, modulus:Int; inline)->Vec2: func modulo(v:Vec2, modulus:Int -> Vec2; inline):
return Vec2(v.x mod modulus, v.y mod modulus) return Vec2(v.x mod modulus, v.y mod modulus)
func modulo1(v:Vec2, modulus:Int; inline)->Vec2: func modulo1(v:Vec2, modulus:Int -> Vec2; inline):
return Vec2(v.x mod1 modulus, v.y mod1 modulus) return Vec2(v.x mod1 modulus, v.y mod1 modulus)
func main(): func main():

View File

@ -1,6 +1,6 @@
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():

View File

@ -1,73 +1,73 @@
struct Struct(x:Int, y:Text): struct Struct(x:Int, y:Text):
func maybe(should_i:Bool)->Struct?: func maybe(should_i:Bool->Struct?):
if should_i: if should_i:
return Struct(123, "hello") return Struct(123, "hello")
else: else:
return !Struct return !Struct
enum Enum(X, Y(y:Int)): enum Enum(X, Y(y:Int)):
func maybe(should_i:Bool)->Enum?: func maybe(should_i:Bool->Enum?):
if should_i: if should_i:
return Enum.Y(123) return Enum.Y(123)
else: else:
return !Enum return !Enum
func maybe_int(should_i:Bool)->Int?: func maybe_int(should_i:Bool->Int?):
if should_i: if should_i:
return 123 return 123
else: else:
return !Int return !Int
func maybe_int64(should_i:Bool)->Int64?: func maybe_int64(should_i:Bool->Int64?):
if should_i: if should_i:
return 123[64] return 123[64]
else: else:
return !Int64 return !Int64
func maybe_array(should_i:Bool)->[Int]?: func maybe_array(should_i:Bool->[Int]?):
if should_i: if should_i:
return [10, 20, 30] return [10, 20, 30]
else: else:
return ![Int] return ![Int]
func maybe_bool(should_i:Bool)->Bool?: func maybe_bool(should_i:Bool->Bool?):
if should_i: if should_i:
return no return no
else: else:
return !Bool return !Bool
func maybe_text(should_i:Bool)->Text?: func maybe_text(should_i:Bool->Text?):
if should_i: if should_i:
return "Hello" return "Hello"
else: else:
return !Text return !Text
func maybe_num(should_i:Bool)->Num?: func maybe_num(should_i:Bool->Num?):
if should_i: if should_i:
return 12.3 return 12.3
else: else:
return !Num return !Num
func maybe_lambda(should_i:Bool)-> func()?: func maybe_lambda(should_i:Bool-> func()?):
if should_i: if should_i:
return func(): say("hi!") return func(): say("hi!")
else: else:
return !func() return !func()
func maybe_c_string(should_i:Bool)->CString?: func maybe_c_string(should_i:Bool->CString?):
if should_i: if should_i:
return ("hi":as_c_string())? return ("hi":as_c_string())?
else: else:
return !CString return !CString
func maybe_channel(should_i:Bool)->|Int|?: func maybe_channel(should_i:Bool->|Int|?):
if should_i: if should_i:
return |:Int|? return |:Int|?
else: else:
return !|Int| return !|Int|
func maybe_thread(should_i:Bool)->Thread?: func maybe_thread(should_i:Bool->Thread?):
if should_i: if should_i:
return Thread.new(func(): pass) return Thread.new(func(): pass)
else: else:

View File

@ -2,7 +2,7 @@ struct ImportedType(name:Text)
needs_initializing := 999999999999999999 needs_initializing := 999999999999999999
func get_value()->ImportedType: func get_value(->ImportedType):
return ImportedType("Hello") return ImportedType("Hello")
func main(): func main():

View File

@ -1138,6 +1138,15 @@ type_t *get_type(env_t *env, ast_t *ast)
if (ret->tag == AbortType) if (ret->tag == AbortType)
ret = Type(VoidType); ret = Type(VoidType);
if (lambda->ret_type) {
type_t *declared = parse_type_ast(env, lambda->ret_type);
if (can_promote(ret, declared))
ret = declared;
else
code_err(ast, "This function was declared to return a value of type %T, but actually returns a value of type %T",
declared, ret);
}
if (has_stack_memory(ret)) if (has_stack_memory(ret))
code_err(ast, "Functions can't return stack references because the reference may outlive its stack frame."); code_err(ast, "Functions can't return stack references because the reference may outlive its stack frame.");
return Type(ClosureType, Type(FunctionType, .args=args, .ret=ret)); return Type(ClosureType, Type(FunctionType, .args=args, .ret=ret));

View File

@ -57,9 +57,8 @@ CORD type_to_cord(type_t *t) {
if (arg->next) c = CORD_cat(c, ", "); if (arg->next) c = CORD_cat(c, ", ");
} }
if (fn->ret && fn->ret->tag != VoidType) if (fn->ret && fn->ret->tag != VoidType)
c = CORD_all(c, ")->", type_to_cord(fn->ret)); c = CORD_all(c, "->", type_to_cord(fn->ret));
else c = CORD_all(c, ")");
c = CORD_all(c, ")");
return c; return c;
} }
case StructType: { case StructType: {