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

3
ast.c
View File

@ -130,7 +130,8 @@ CORD ast_to_xml(ast_t *ast)
optional_tagged("filter", data.filter))
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))
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(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))

1
ast.h
View File

@ -233,6 +233,7 @@ struct ast_s {
} FunctionDef;
struct {
arg_ast_t *args;
type_ast_t *ret_type;
ast_t *body;
int64_t id;
} 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);
if (ret_t->tag == ReturnType)
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;
if (env->fn_ctx->closed_vars) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -79,7 +79,7 @@ calculated.
**Usage:**
```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:**
@ -113,7 +113,7 @@ specifier, which gives the date in `YYYY-MM-DD` form.
**Usage:**
```markdown
datetime:date(timezone : Text? = !Text) -> Text
datetime:date(timezone : Text? = !Text -> Text)
```
**Parameters:**
@ -141,7 +141,7 @@ timezone.
**Usage:**
```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:**
@ -168,7 +168,7 @@ the given UNIX epoch timestamp (seconds since January 1, 1970 UTC).
**Usage:**
```markdown
DateTime.from_unix_timestamp(timestamp: Int64) -> DateTime
DateTime.from_unix_timestamp(timestamp: Int64 -> DateTime)
```
**Parameters:**
@ -195,7 +195,7 @@ provided optional fields.
**Usage:**
```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:**
@ -233,7 +233,7 @@ calling `DateTime.set_local_timezone(...)`.
**Usage:**
```markdown
DateTime.get_local_timezone() -> Text
DateTime.get_local_timezone(->Text)
```
**Parameters:**
@ -258,7 +258,7 @@ Return the number of hours until a given datetime.
**Usage:**
```markdown
datetime:hours_till(then:DateTime) -> Num
datetime:hours_till(then:DateTime -> Num)
```
**Parameters:**
@ -284,7 +284,7 @@ Return the number of minutes until a given datetime.
**Usage:**
```markdown
datetime:minutes_till(then:DateTime) -> Num
datetime:minutes_till(then:DateTime -> Num)
```
**Parameters:**
@ -312,7 +312,7 @@ constructor.
**Usage:**
```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:**
@ -351,7 +351,7 @@ is the same as the global function `now()`.
**Usage:**
```markdown
DateTime.now() -> DateTime
DateTime.now(->DateTime)
```
**Parameters:**
@ -377,7 +377,7 @@ or a null value if the value could not be successfully parsed.
**Usage:**
```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:**
@ -410,7 +410,7 @@ between two `DateTime`s. For example: `5 minutes ago` or `1 day later`
**Usage:**
```markdown
datetime:relative(relative_to : DateTime = DateTime.now(), timezone : Text? = !Text) -> Text
datetime:relative(relative_to : DateTime = DateTime.now(), timezone : Text? = !Text -> Text)
```
**Parameters:**
@ -445,7 +445,7 @@ Return the number of seconds until a given datetime.
**Usage:**
```markdown
datetime:seconds_till(then:DateTime) -> Num
datetime:seconds_till(then:DateTime -> Num)
```
**Parameters:**
@ -475,7 +475,7 @@ converted to text.
**Usage:**
```markdown
DateTime.set_local_timezone(timezone : Text? = !Text) -> Void
DateTime.set_local_timezone(timezone : Text? = !Text -> Void)
```
**Parameters:**
@ -501,7 +501,7 @@ Return a text representation of the time component of the given datetime.
**Usage:**
```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:**
@ -537,7 +537,7 @@ January 1, 1970 UTC).
**Usage:**
```markdown
datetime:unix_timestamp() -> Int64
datetime:unix_timestamp(->Int64)
```
**Parameters:**

View File

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

View File

@ -3,7 +3,7 @@
In Tomo, you can define functions with the `func` keyword:
```tomo
func add(x:Int, y:Int)->Int:
func add(x:Int, y:Int -> Int):
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).
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
@ -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:
```tomo
func increment(x:Int, amount=1)->Int:
func increment(x:Int, amount=1 -> Int):
return x + amount
```
@ -35,7 +35,7 @@ callsite:
```
**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
random number.
@ -68,7 +68,7 @@ Tomo supports automatic function caching using the `cached` or `cache_size=N`
attributes on a function definition:
```tomo
func add(x, y:Int; cached)->Int:
func add(x, y:Int -> Int; cached):
return x + y
```
@ -78,13 +78,13 @@ return value for those arguments. The above example is functionally similar to
the following code:
```tomo
func _add(x, y:Int)->Int:
func _add(x, y:Int -> Int):
return x + y
struct add_args(x,y:Int)
add_cache := @{:add_args:Int}
func add(x, y:Int)->Int:
func add(x, y:Int -> Int):
args := add_args(x, y)
if add_cache:has(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:
```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"
```
@ -108,7 +108,7 @@ Functions can also be given an `inline` attribute, which encourages the
compiler to inline the function when possible:
```tomo
func add(x, y:Int; inline)->Int:
func add(x, y:Int -> Int; inline):
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
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
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
@ -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.**
```tomo
func create_adder(n:Int) -> func(i:Int)->Int:
func create_adder(n:Int -> func(i:Int -> Int)):
adder := func(i:Int):
return n + i

View File

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

View File

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

View File

@ -3,25 +3,25 @@
This language relies on a small set of "metamethods" which define special
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
include ANSI escape codes for syntax highlighting. If the `obj` pointer is
`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
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
as greater than any other number value and `NaN` values are compared bitwise
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
`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
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
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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -88,130 +88,130 @@ env_t *new_compilation_unit(CORD libname)
{"Void", Type(VoidType), "Void_t", "Void$info", {}},
{"Memory", Type(MemoryType), "Memory_t", "Memory$info", {}},
{"Bool", Type(BoolType), "Bool_t", "Bool$info", TypedArray(ns_entry_t,
{"from_text", "Bool$from_text", "func(text:Text)->Bool?"},
{"random", "Bool$random", "func(p=0.5)->Bool"},
{"from_text", "Bool$from_text", "func(text:Text -> Bool?)"},
{"random", "Bool$random", "func(p=0.5 -> Bool)"},
)},
{"Byte", Type(ByteType), "Byte_t", "Byte$info", TypedArray(ns_entry_t,
{"max", "Byte$max", "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,
{"abs", "Int$abs", "func(x:Int)->Int"},
{"bit_and", "Int$bit_and", "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"},
{"clamped", "Int$clamped", "func(x,low,high:Int)->Int"},
{"divided_by", "Int$divided_by", "func(x,y:Int)->Int"},
{"format", "Int$format", "func(i:Int, digits=0)->Text"},
{"from_text", "Int$from_text", "func(text:Text)->Int?"},
{"hex", "Int$hex", "func(i:Int, digits=0, uppercase=yes, prefix=yes)->Text"},
{"is_prime", "Int$is_prime", "func(x:Int,reps=50)->Bool"},
{"left_shifted", "Int$left_shifted", "func(x,y:Int)->Int"},
{"minus", "Int$minus", "func(x,y:Int)->Int"},
{"modulo", "Int$modulo", "func(x,y:Int)->Int"},
{"modulo1", "Int$modulo1", "func(x,y:Int)->Int"},
{"negated", "Int$negated", "func(x:Int)->Int"},
{"negative", "Int$negative", "func(x:Int)->Int"},
{"next_prime", "Int$next_prime", "func(x:Int)->Int"},
{"octal", "Int$octal", "func(i:Int, digits=0, prefix=yes)->Text"},
{"plus", "Int$plus", "func(x,y:Int)->Int"},
{"power", "Int$power", "func(base:Int,exponent:Int)->Int"},
{"prev_prime", "Int$prev_prime", "func(x:Int)->Int"},
{"random", "Int$random", "func(min,max:Int)->Int"},
{"right_shifted", "Int$right_shifted", "func(x,y:Int)->Int"},
{"sqrt", "Int$sqrt", "func(x:Int)->Int"},
{"times", "Int$times", "func(x,y:Int)->Int"},
{"to", "Int$to", "func(from:Int,to:Int)->Range"},
{"abs", "Int$abs", "func(x:Int -> Int)"},
{"bit_and", "Int$bit_and", "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)"},
{"clamped", "Int$clamped", "func(x,low,high:Int -> Int)"},
{"divided_by", "Int$divided_by", "func(x,y:Int -> Int)"},
{"format", "Int$format", "func(i:Int, digits=0 -> Text)"},
{"from_text", "Int$from_text", "func(text:Text -> Int?)"},
{"hex", "Int$hex", "func(i:Int, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"is_prime", "Int$is_prime", "func(x:Int,reps=50 -> Bool)"},
{"left_shifted", "Int$left_shifted", "func(x,y:Int -> Int)"},
{"minus", "Int$minus", "func(x,y:Int -> Int)"},
{"modulo", "Int$modulo", "func(x,y:Int -> Int)"},
{"modulo1", "Int$modulo1", "func(x,y:Int -> Int)"},
{"negated", "Int$negated", "func(x:Int -> Int)"},
{"negative", "Int$negative", "func(x:Int -> Int)"},
{"next_prime", "Int$next_prime", "func(x:Int -> Int)"},
{"octal", "Int$octal", "func(i:Int, digits=0, prefix=yes -> Text)"},
{"plus", "Int$plus", "func(x,y:Int -> Int)"},
{"power", "Int$power", "func(base:Int,exponent:Int -> Int)"},
{"prev_prime", "Int$prev_prime", "func(x:Int -> Int)"},
{"random", "Int$random", "func(min,max:Int -> Int)"},
{"right_shifted", "Int$right_shifted", "func(x,y:Int -> Int)"},
{"sqrt", "Int$sqrt", "func(x:Int -> Int)"},
{"times", "Int$times", "func(x,y:Int -> Int)"},
{"to", "Int$to", "func(from:Int,to:Int -> Range)"},
)},
{"Int64", Type(IntType, .bits=TYPE_IBITS64), "Int64_t", "Int64$info", TypedArray(ns_entry_t,
{"abs", "labs", "func(i:Int64)->Int64"},
{"bits", "Int64$bits", "func(x:Int64)->[Bool]"},
{"clamped", "Int64$clamped", "func(x,low,high:Int64)->Int64"},
{"divided_by", "Int64$divided_by", "func(x,y:Int64)->Int64"},
{"format", "Int64$format", "func(i:Int64, digits=0)->Text"},
{"from_text", "Int64$from_text", "func(text:Text)->Int64?"},
{"hex", "Int64$hex", "func(i:Int64, digits=0, uppercase=yes, prefix=yes)->Text"},
{"abs", "labs", "func(i:Int64 -> Int64)"},
{"bits", "Int64$bits", "func(x:Int64 -> [Bool])"},
{"clamped", "Int64$clamped", "func(x,low,high:Int64 -> Int64)"},
{"divided_by", "Int64$divided_by", "func(x,y:Int64 -> Int64)"},
{"format", "Int64$format", "func(i:Int64, digits=0 -> Text)"},
{"from_text", "Int64$from_text", "func(text:Text -> Int64?)"},
{"hex", "Int64$hex", "func(i:Int64, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"max", "Int64$max", "Int64"},
{"min", "Int64$min", "Int64"},
{"modulo", "Int64$modulo", "func(x,y:Int64)->Int64"},
{"modulo1", "Int64$modulo1", "func(x,y:Int64)->Int64"},
{"octal", "Int64$octal", "func(i:Int64, digits=0, prefix=yes)->Text"},
{"to", "Int64$to", "func(from:Int64,to:Int64)->Range"},
{"modulo", "Int64$modulo", "func(x,y:Int64 -> Int64)"},
{"modulo1", "Int64$modulo1", "func(x,y:Int64 -> Int64)"},
{"octal", "Int64$octal", "func(i:Int64, digits=0, prefix=yes -> Text)"},
{"to", "Int64$to", "func(from:Int64,to:Int64 -> Range)"},
// 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,
{"abs", "abs", "func(i:Int32)->Int32"},
{"bits", "Int32$bits", "func(x:Int32)->[Bool]"},
{"clamped", "Int32$clamped", "func(x,low,high:Int32)->Int32"},
{"divided_by", "Int32$divided_by", "func(x,y:Int32)->Int32"},
{"format", "Int32$format", "func(i:Int32, digits=0)->Text"},
{"from_text", "Int32$from_text", "func(text:Text)->Int32?"},
{"hex", "Int32$hex", "func(i:Int32, digits=0, uppercase=yes, prefix=yes)->Text"},
{"abs", "abs", "func(i:Int32 -> Int32)"},
{"bits", "Int32$bits", "func(x:Int32 -> [Bool])"},
{"clamped", "Int32$clamped", "func(x,low,high:Int32 -> Int32)"},
{"divided_by", "Int32$divided_by", "func(x,y:Int32 -> Int32)"},
{"format", "Int32$format", "func(i:Int32, digits=0 -> Text)"},
{"from_text", "Int32$from_text", "func(text:Text -> Int32?)"},
{"hex", "Int32$hex", "func(i:Int32, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"max", "Int32$max", "Int32"},
{"min", "Int32$min", "Int32"},
{"modulo", "Int32$modulo", "func(x,y:Int32)->Int32"},
{"modulo1", "Int32$modulo1", "func(x,y:Int32)->Int32"},
{"octal", "Int32$octal", "func(i:Int32, digits=0, prefix=yes)->Text"},
{"to", "Int32$to", "func(from:Int32,to:Int32)->Range"},
{"modulo", "Int32$modulo", "func(x,y:Int32 -> Int32)"},
{"modulo1", "Int32$modulo1", "func(x,y:Int32 -> Int32)"},
{"octal", "Int32$octal", "func(i:Int32, digits=0, prefix=yes -> Text)"},
{"to", "Int32$to", "func(from:Int32,to:Int32 -> Range)"},
// 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,
{"abs", "abs", "func(i:Int16)->Int16"},
{"bits", "Int16$bits", "func(x:Int16)->[Bool]"},
{"clamped", "Int16$clamped", "func(x,low,high:Int16)->Int16"},
{"divided_by", "Int16$divided_by", "func(x,y:Int16)->Int16"},
{"format", "Int16$format", "func(i:Int16, digits=0)->Text"},
{"from_text", "Int16$from_text", "func(text:Text)->Int16?"},
{"hex", "Int16$hex", "func(i:Int16, digits=0, uppercase=yes, prefix=yes)->Text"},
{"abs", "abs", "func(i:Int16 -> Int16)"},
{"bits", "Int16$bits", "func(x:Int16 -> [Bool])"},
{"clamped", "Int16$clamped", "func(x,low,high:Int16 -> Int16)"},
{"divided_by", "Int16$divided_by", "func(x,y:Int16 -> Int16)"},
{"format", "Int16$format", "func(i:Int16, digits=0 -> Text)"},
{"from_text", "Int16$from_text", "func(text:Text -> Int16?)"},
{"hex", "Int16$hex", "func(i:Int16, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"max", "Int16$max", "Int16"},
{"min", "Int16$min", "Int16"},
{"modulo", "Int16$modulo", "func(x,y:Int16)->Int16"},
{"modulo1", "Int16$modulo1", "func(x,y:Int16)->Int16"},
{"octal", "Int16$octal", "func(i:Int16, digits=0, prefix=yes)->Text"},
{"to", "Int16$to", "func(from:Int16,to:Int16)->Range"},
{"modulo", "Int16$modulo", "func(x,y:Int16 -> Int16)"},
{"modulo1", "Int16$modulo1", "func(x,y:Int16 -> Int16)"},
{"octal", "Int16$octal", "func(i:Int16, digits=0, prefix=yes -> Text)"},
{"to", "Int16$to", "func(from:Int16,to:Int16 -> Range)"},
// 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,
{"abs", "abs", "func(i:Int8)->Int8"},
{"bits", "Int8$bits", "func(x:Int8)->[Bool]"},
{"clamped", "Int8$clamped", "func(x,low,high:Int8)->Int8"},
{"divided_by", "Int8$divided_by", "func(x,y:Int8)->Int8"},
{"format", "Int8$format", "func(i:Int8, digits=0)->Text"},
{"from_text", "Int8$from_text", "func(text:Text)->Int8?"},
{"hex", "Int8$hex", "func(i:Int8, digits=0, uppercase=yes, prefix=yes)->Text"},
{"abs", "abs", "func(i:Int8 -> Int8)"},
{"bits", "Int8$bits", "func(x:Int8 -> [Bool])"},
{"clamped", "Int8$clamped", "func(x,low,high:Int8 -> Int8)"},
{"divided_by", "Int8$divided_by", "func(x,y:Int8 -> Int8)"},
{"format", "Int8$format", "func(i:Int8, digits=0 -> Text)"},
{"from_text", "Int8$from_text", "func(text:Text -> Int8?)"},
{"hex", "Int8$hex", "func(i:Int8, digits=0, uppercase=yes, prefix=yes -> Text)"},
{"max", "Int8$max", "Int8"},
{"min", "Int8$min", "Int8"},
{"modulo", "Int8$modulo", "func(x,y:Int8)->Int8"},
{"modulo1", "Int8$modulo1", "func(x,y:Int8)->Int8"},
{"octal", "Int8$octal", "func(i:Int8, digits=0, prefix=yes)->Text"},
{"to", "Int8$to", "func(from:Int8,to:Int8)->Range"},
{"modulo", "Int8$modulo", "func(x,y:Int8 -> Int8)"},
{"modulo1", "Int8$modulo1", "func(x,y:Int8 -> Int8)"},
{"octal", "Int8$octal", "func(i:Int8, digits=0, prefix=yes -> Text)"},
{"to", "Int8$to", "func(from:Int8,to:Int8 -> Range)"},
// 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 F(name) {#name, #name, "func(n:Num)->Num"}
#define F2(name) {#name, #name, "func(x,y:Num)->Num"}
#define F(name) {#name, #name, "func(n: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,
{"near", "Num$near", "func(x,y:Num, ratio=1e-9, min_epsilon=1e-9)->Bool"},
{"clamped", "Num$clamped", "func(x,low,high:Num)->Num"},
{"format", "Num$format", "func(n:Num, precision=0)->Text"},
{"scientific", "Num$scientific", "func(n:Num, precision=0)->Text"},
{"nan", "Num$nan", "func(tag=\"\")->Num"},
{"isinf", "Num$isinf", "func(n:Num)->Bool"},
{"isfinite", "Num$isfinite", "func(n:Num)->Bool"},
{"isnan", "Num$isnan", "func(n:Num)->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)"},
{"format", "Num$format", "func(n:Num, precision=0 -> Text)"},
{"scientific", "Num$scientific", "func(n:Num,precision=0 -> Text)"},
{"nan", "Num$nan", "func(tag=\"\" -> Num)"},
{"isinf", "Num$isinf", "func(n:Num -> Bool)"},
{"isfinite", "Num$isfinite", "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(PI), C(PI_4), C(SQRT2), C(SQRT1_2),
{"INF", "(Num_t)(INFINITY)", "Num"},
{"TAU", "(Num_t)(2.*M_PI)", "Num"},
{"random", "Num$random", "func()->Num"},
{"mix", "Num$mix", "func(amount,x,y:Num)->Num"},
{"from_text", "Num$from_text", "func(text:Text)->Num?"},
{"abs", "fabs", "func(n:Num)->Num"},
{"random", "Num$random", "func(->Num)"},
{"mix", "Num$mix", "func(amount,x,y:Num -> Num)"},
{"from_text", "Num$from_text", "func(text:Text -> 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(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),
@ -222,25 +222,25 @@ env_t *new_compilation_unit(CORD libname)
#undef F
#undef C
#define C(name) {#name, "(Num32_t)(M_"#name")", "Num32"}
#define F(name) {#name, #name"f", "func(n:Num32)->Num32"}
#define F2(name) {#name, #name"f", "func(x,y:Num32)->Num32"}
#define F(name) {#name, #name"f", "func(n: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,
{"near", "Num32$near", "func(x,y:Num32, ratio=1e-9f32, min_epsilon=1e-9f32)->Bool"},
{"clamped", "Num32$clamped", "func(x,low,high:Num32)->Num32"},
{"format", "Num32$format", "func(n:Num32, precision=0)->Text"},
{"scientific", "Num32$scientific", "func(n:Num32, precision=0)->Text"},
{"nan", "Num32$nan", "func(tag=\"\")->Num32"},
{"isinf", "Num32$isinf", "func(n:Num32)->Bool"},
{"isfinite", "Num32$isfinite", "func(n:Num32)->Bool"},
{"isnan", "Num32$isnan", "func(n:Num32)->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)"},
{"format", "Num32$format", "func(n:Num32, precision=0 -> Text)"},
{"scientific", "Num32$scientific", "func(n:Num32, precision=0 -> Text)"},
{"nan", "Num32$nan", "func(tag=\"\" -> Num32)"},
{"isinf", "Num32$isinf", "func(n:Num32 -> Bool)"},
{"isfinite", "Num32$isfinite", "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(PI), C(PI_4), C(SQRT2), C(SQRT1_2),
{"INF", "(Num32_t)(INFINITY)", "Num32"},
{"TAU", "(Num32_t)(2.f*M_PI)", "Num32"},
{"random", "Num32$random", "func()->Num32"},
{"mix", "Num32$mix", "func(amount,x,y:Num32)->Num32"},
{"from_text", "Num32$from_text", "func(text:Text)->Num32?"},
{"abs", "fabsf", "func(n:Num32)->Num32"},
{"random", "Num32$random", "func(->Num32)"},
{"mix", "Num32$mix", "func(amount,x,y:Num32 -> Num32)"},
{"from_text", "Num32$from_text", "func(text:Text -> 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(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),
@ -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),
)},
{"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 F
#undef C
{"Range", RANGE_TYPE, "Range_t", "Range", TypedArray(ns_entry_t,
{"reversed", "Range$reversed", "func(range:Range)->Range"},
{"by", "Range$by", "func(range:Range, step:Int)->Range"},
{"reversed", "Range$reversed", "func(range:Range -> 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,
{"escape_int", "Int$value_as_text", "func(i:Int)->Pattern"},
{"escape_text", "Pattern$escape_text", "func(text:Text)->Pattern"},
{"escape_int", "Int$value_as_text", "func(i:Int -> Pattern)"},
{"escape_text", "Pattern$escape_text", "func(text:Text -> Pattern)"},
)},
{"DateTime", Type(DateTimeType), "DateTime_t", "DateTime", TypedArray(ns_entry_t,
// 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"},
{"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"},
{"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_local_timezone", "DateTime$get_local_timezone", "func()->Text"},
{"hours_till", "DateTime$hours_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"},
{"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"},
{"seconds_till", "DateTime$seconds_till", "func(now:DateTime,then:DateTime)->Num"},
{"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)"},
{"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)"},
{"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)"},
{"hours_till", "DateTime$hours_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)"},
{"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)"},
{"seconds_till", "DateTime$seconds_till", "func(now:DateTime,then:DateTime -> Num)"},
{"set_local_timezone", "DateTime$set_local_timezone", "func(timezone=!Text)"},
{"time", "DateTime$time", "func(dt:DateTime,seconds=no,am_pm=yes,timezone=!Text)->Text"},
{"unix_timestamp", "DateTime$unix_timestamp", "func(dt:DateTime)->Int64"},
{"time", "DateTime$time", "func(dt:DateTime,seconds=no,am_pm=yes,timezone=!Text -> Text)"},
{"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,
{"append", "Path$append", "func(path:Path, text:Text, 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"},
{"by_line", "Path$by_line", "func(path:Path)->(func()->Text?)?"},
{"children", "Path$children", "func(path:Path, include_hidden=no)->[Path]"},
{"base_name", "Path$base_name", "func(path:Path -> Text)"},
{"by_line", "Path$by_line", "func(path:Path -> func(->Text?)?)"},
{"children", "Path$children", "func(path:Path, include_hidden=no -> [Path])"},
{"create_directory", "Path$create_directory", "func(path:Path, permissions=0o755[32])"},
{"escape_int", "Int$value_as_text", "func(i:Int)->Path"},
{"escape_path", "Path$escape_path", "func(path:Path)->Path"},
{"escape_text", "Path$escape_text", "func(text:Text)->Path"},
{"exists", "Path$exists", "func(path:Path)->Bool"},
{"extension", "Path$extension", "func(path:Path, full=yes)->Text"},
{"files", "Path$children", "func(path:Path, include_hidden=no)->[Path]"},
{"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_pipe", "Path$is_pipe", "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"},
{"parent", "Path$parent", "func(path:Path)->Path"},
{"read", "Path$read", "func(path:Path)->Text?"},
{"read_bytes", "Path$read_bytes", "func(path:Path)->[Byte]?"},
{"relative", "Path$relative", "func(path:Path, relative_to=(./))->Path"},
{"escape_int", "Int$value_as_text", "func(i:Int -> Path)"},
{"escape_path", "Path$escape_path", "func(path:Path -> Path)"},
{"escape_text", "Path$escape_text", "func(text:Text -> Path)"},
{"exists", "Path$exists", "func(path:Path -> Bool)"},
{"extension", "Path$extension", "func(path:Path, full=yes -> Text)"},
{"files", "Path$children", "func(path:Path, include_hidden=no -> [Path])"},
{"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_pipe", "Path$is_pipe", "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)"},
{"parent", "Path$parent", "func(path:Path -> Path)"},
{"read", "Path$read", "func(path:Path -> Text?)"},
{"read_bytes", "Path$read_bytes", "func(path:Path -> [Byte]?)"},
{"relative", "Path$relative", "func(path:Path, relative_to=(./) -> Path)"},
{"remove", "Path$remove", "func(path:Path, ignore_missing=no)"},
{"resolved", "Path$resolved", "func(path:Path, relative_to=(./))->Path"},
{"subdirectories", "Path$children", "func(path:Path, include_hidden=no)->[Path]"},
{"unique_directory", "Path$unique_directory", "func(path:Path)->Path"},
{"resolved", "Path$resolved", "func(path:Path, relative_to=(./) -> Path)"},
{"subdirectories", "Path$children", "func(path:Path, include_hidden=no -> [Path])"},
{"unique_directory", "Path$unique_directory", "func(path:Path -> Path)"},
{"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_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", "Path$write_unique", "func(path:Path, text:Text -> Path)"},
{"write_unique_bytes", "Path$write_unique_bytes", "func(path:Path, bytes:[Byte] -> Path)"},
{"modified", "Path$modified", "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?"},
{"modified", "Path$modified", "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?)"},
// Text methods:
{"ends_with", "Text$ends_with", "func(path:Path, suffix:Text)->Bool"},
{"has", "Text$has", "func(path:Path, pattern:Pattern)->Bool"},
{"matches", "Text$matches", "func(path:Path, pattern:Pattern)->[Text]?"},
{"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"},
{"starts_with", "Text$starts_with", "func(path:Path, prefix:Text)->Bool"},
{"ends_with", "Text$ends_with", "func(path:Path, suffix:Text -> Bool)"},
{"has", "Text$has", "func(path:Path, pattern:Pattern -> Bool)"},
{"matches", "Text$matches", "func(path:Path, pattern:Pattern -> [Text]?)"},
{"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)"},
{"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,
{"by_line", "Shell$by_line", "func(command:Shell)->(func()->Text?)?"},
{"escape_int", "Int$value_as_text", "func(i:Int)->Shell"},
{"escape_text", "Shell$escape_text", "func(text:Text)->Shell"},
{"escape_text_array", "Shell$escape_text_array", "func(texts:[Text])->Shell"},
{"run_bytes", "Shell$run", "func(command:Shell)->[Byte]?"},
{"run", "Shell$run", "func(command:Shell)->Text?"},
{"by_line", "Shell$by_line", "func(command:Shell -> func(->Text?)?)"},
{"escape_int", "Int$value_as_text", "func(i:Int -> Shell)"},
{"escape_text", "Shell$escape_text", "func(text:Text -> Shell)"},
{"escape_text_array", "Shell$escape_text_array", "func(texts:[Text] -> Shell)"},
{"run_bytes", "Shell$run", "func(command:Shell -> [Byte]?)"},
{"run", "Shell$run", "func(command:Shell -> Text?)"},
)},
{"Text", TEXT_TYPE, "Text_t", "Text$info", TypedArray(ns_entry_t,
{"as_c_string", "Text$as_c_string", "func(text:Text)->CString"},
{"codepoint_names", "Text$codepoint_names", "func(text:Text)->[Text]"},
{"ends_with", "Text$ends_with", "func(text,suffix:Text)->Bool"},
{"find", "Text$find", "func(text:Text, pattern:Pattern, start=1, length=!&Int64)->Int"},
{"find_all", "Text$find_all", "func(text:Text, pattern:Pattern)->[Text]"},
{"from_bytes", "Text$from_bytes", "func(bytes:[Byte])->Text"},
{"from_c_string", "Text$from_str", "func(str:CString)->Text"},
{"from_codepoint_names", "Text$from_codepoint_names", "func(codepoint_names:[Text])->Text"},
{"from_codepoints", "Text$from_codepoints", "func(codepoints:[Int32])->Text"},
{"without_escaping", "Path$cleanup", "func(text:Text)->Path"},
{"has", "Text$has", "func(text:Text, pattern:Pattern)->Bool"},
{"join", "Text$join", "func(glue:Text, pieces:[Text])->Text"},
{"lines", "Text$lines", "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"},
{"matches", "Text$matches", "func(text:Text, pattern:Pattern)->[Text]?"},
{"quoted", "Text$quoted", "func(text:Text, color=no)->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_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"},
{"split", "Text$split", "func(text:Text, pattern=$Pattern'')->[Text]"},
{"starts_with", "Text$starts_with", "func(text,prefix:Text)->Bool"},
{"title", "Text$title", "func(text:Text)->Text"},
{"trim", "Text$trim", "func(text:Text, pattern=$/{whitespace}/, trim_left=yes, trim_right=yes)->Text"},
{"upper", "Text$upper", "func(text:Text)->Text"},
{"utf32_codepoints", "Text$utf32_codepoints", "func(text:Text)->[Int32]"},
{"utf8_bytes", "Text$utf8_bytes", "func(text:Text)->[Byte]"},
{"as_c_string", "Text$as_c_string", "func(text:Text -> CString)"},
{"codepoint_names", "Text$codepoint_names", "func(text:Text -> [Text])"},
{"ends_with", "Text$ends_with", "func(text,suffix:Text -> Bool)"},
{"find", "Text$find", "func(text:Text, pattern:Pattern, start=1, length=!&Int64 -> Int)"},
{"find_all", "Text$find_all", "func(text:Text, pattern:Pattern -> [Text])"},
{"from_bytes", "Text$from_bytes", "func(bytes:[Byte] -> Text)"},
{"from_c_string", "Text$from_str", "func(str:CString -> Text)"},
{"from_codepoint_names", "Text$from_codepoint_names", "func(codepoint_names:[Text] -> Text)"},
{"from_codepoints", "Text$from_codepoints", "func(codepoints:[Int32] -> Text)"},
{"without_escaping", "Path$cleanup", "func(text:Text -> Path)"},
{"has", "Text$has", "func(text:Text, pattern:Pattern -> Bool)"},
{"join", "Text$join", "func(glue:Text, pieces:[Text] -> Text)"},
{"lines", "Text$lines", "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)"},
{"matches", "Text$matches", "func(text:Text, pattern:Pattern -> [Text]?)"},
{"quoted", "Text$quoted", "func(text:Text, color=no -> 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_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)"},
{"split", "Text$split", "func(text:Text, pattern=$Pattern'' -> [Text])"},
{"starts_with", "Text$starts_with", "func(text,prefix:Text -> Bool)"},
{"title", "Text$title", "func(text:Text -> Text)"},
{"trim", "Text$trim", "func(text:Text, pattern=$/{whitespace}/, trim_left=yes, trim_right=yes -> Text)"},
{"upper", "Text$upper", "func(text:Text -> Text)"},
{"utf32_codepoints", "Text$utf32_codepoints", "func(text:Text -> [Int32])"},
{"utf8_bytes", "Text$utf8_bytes", "func(text:Text -> [Byte])"},
)},
{"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)"},
{"join", "Thread$join", "func(thread:Thread)"},
{"detach", "Thread$detach", "func(thread:Thread)"},

View File

@ -6,7 +6,7 @@ use <raymath.h>
use ./world.tm
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")
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)
SetTargetFPS(60)
extern WindowShouldClose:func()->Bool
extern WindowShouldClose:func(->Bool)
while not WindowShouldClose():
extern GetFrameTime:func()->Num32
extern GetFrameTime:func(->Num32)
dt := GetFrameTime()
World.CURRENT:update(Num(dt))

View File

@ -6,7 +6,7 @@ use ./color.tm
use ./box.tm
# 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_right := a_pos.x + a_size.x
a_top := a_pos.y

View File

@ -7,7 +7,7 @@ struct HTTPResponse(code:Int, body:Text)
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]
save_chunk := func(chunk:CString, size:Int64, n:Int64):
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))
func get(url:Text, headers=[:Text])->HTTPResponse:
func get(url:Text, headers=[:Text] -> HTTPResponse):
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)
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)
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)
func main():

View File

@ -6,7 +6,7 @@ _HELP := "
$_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)$\[]")
sections := {:Text:@{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
# 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
# Default values for arguments can be provided in place of a type (the type is
# 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"
func demo_keyword_args():
@ -241,7 +241,7 @@ func takes_many_types(
table_of_text_to_bools:{Text:Bool},
pointer_to_mutable_array_of_ints:@[Int],
optional_int:Int?,
function_from_int_to_text:func(x:Int)->Text,
function_from_int_to_text:func(x:Int -> Text),
):
pass
@ -259,7 +259,7 @@ struct Person(name:Text, age:Int):
self.age += amount
# Methods don't have to take a Person as their first argument:
func get_cool_name()->Text:
func get_cool_name(->Text):
return "Blade"
func demo_structs():
@ -304,7 +304,7 @@ enum Shape(
):
# Just like with structs, you define methods and constants inside a level
# 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'
# statement to get the internal values:
when self is Point:

View File

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

View File

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

View File

@ -2,32 +2,32 @@
struct Vec2(x,y:Num):
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)
func minus(a,b:Vec2; inline)->Vec2:
func minus(a,b:Vec2->Vec2; inline):
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)
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)
func cross(a,b:Vec2; inline)->Num:
func cross(a,b:Vec2->Num; inline):
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)
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)
func length(v:Vec2; inline)->Num:
func length(v:Vec2->Num; inline):
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()
func angle(v:Vec2; inline)->Num:
func angle(v:Vec2->Num; inline):
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:
return v
len := v:length()
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(
amount:mix(a.x, b.x),
amount:mix(a.y, b.y),
@ -35,30 +35,30 @@ struct Vec2(x,y:Num):
struct Vec3(x,y,z:Num):
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)
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)
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)
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)
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)
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)
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)
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()
func dist(a,b:Vec3; inline)->Num:
func dist(a,b:Vec3->Num; inline):
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:
return v
len := v:length()
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(
amount:mix(a.x, b.x),
amount:mix(a.y, b.y),
@ -68,46 +68,46 @@ struct Vec3(x,y,z:Num):
struct IVec2(x,y:Int):
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)
func minus(a,b:IVec2; inline)->IVec2:
func minus(a,b:IVec2->IVec2; inline):
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)
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)
func cross(a,b:IVec2; inline)->Int:
func cross(a,b:IVec2->Int; inline):
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)
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)
func length(v:IVec2; inline)->Num:
func length(v:IVec2->Num; inline):
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()
func angle(v:IVec2; inline)->Num:
func angle(v:IVec2->Num; inline):
return Num.atan2(v.y, v.x)
struct IVec3(x,y,z:Int):
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)
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)
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)
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)
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)
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)
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)
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)
func dist(a,b:IVec3; inline)->Num:
func dist(a,b:IVec3->Num; inline):
return a:minus(b):length()
func main():

View File

@ -13,7 +13,7 @@ HELP := "
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:
paragraphs := text:split($/{2+ nl}/)
if paragraphs.length > 1:
@ -21,7 +21,7 @@ func unwrap(text:Text, preserve_paragraphs=yes, hyphen=UNICODE_HYPHEN)->Text:
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:
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)
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 == "":
return letters.length <= width
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);
if (!match(&pos, "(")) return NULL;
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);
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);
}
@ -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) {
const char *start = pos;
type_ast_t *type = parse_non_optional_type(ctx, pos);
if (!type) return NULL;
pos = type->end;
spaces(&pos);
if (match(&pos, "?"))
@ -1548,10 +1549,12 @@ PARSER(parse_lambda) {
return NULL;
arg_ast_t *args = parse_args(ctx, &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");
ast_t *body = optional(ctx, &pos, parse_block);
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) {
@ -2242,6 +2245,8 @@ PARSER(parse_func_def) {
if (!match(&pos, "(")) return NULL;
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);
bool is_inline = false;
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");
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,
"This function needs a body block");
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:
return ["ping: $x"] ++ pong(x-1)
else:
return ["ping: $x"]
func pong(x:Int)->[Text]:
func pong(x:Int->[Text]):
if x > 0:
return ["pong: $x"] ++ ping(x-1)
else:

View File

@ -76,7 +76,7 @@ func defer_func(return_early=no):
say("Finished defer_func")
func make_counter()->func()->Int:
func make_counter(->func(->Int)):
i := 1
return func():
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))
func choose_text(f:Foo)->Text:
func choose_text(f:Foo->Text):
>> f
when f is Zero:
return "Zero"

View File

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

View File

@ -1,5 +1,5 @@
func all_nums(nums:[Int])->Text:
func all_nums(nums:[Int] -> Text):
result := ""
for num in nums:
result ++= "$num,"
@ -7,7 +7,7 @@ func all_nums(nums:[Int])->Text:
return "EMPTY"
return result
func labeled_nums(nums:[Int])->Text:
func labeled_nums(nums:[Int] -> Text):
result := ""
for i,num in nums:
result ++= "$i:$num,"
@ -15,14 +15,14 @@ func labeled_nums(nums:[Int])->Text:
return "EMPTY"
return result
func table_str(t:{Text:Text})->Text:
func table_str(t:{Text:Text} -> Text):
str := ""
for k,v in t:
str ++= "$k:$v,"
else: return "EMPTY"
return str
func table_key_str(t:{Text:Text})->Text:
func table_key_str(t:{Text:Text} -> Text):
str := ""
for k in t:
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
func cached_heap(x:Int; cached)->@Int:
func cached_heap(x:Int->@Int; cached):
return @x
func main():

View File

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

View File

@ -1,14 +1,14 @@
struct Pair(x:Text, y:Text)
func pairwise(strs:[Text])->func()->Pair?:
func pairwise(strs:[Text] -> func(->Pair?)):
i := 1
return func():
if i + 1 > strs.length: return !Pair
i += 1
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
return func():
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
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
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)
func main():

View File

@ -1,6 +1,6 @@
lang HTML:
HEADER := $HTML"<!DOCTYPE HTML>"
func escape(t:Text)->HTML:
func escape(t:Text->HTML):
t = t:replace_all({
$/&/: "&amp;",
$/</: "&lt;",
@ -11,10 +11,10 @@ lang HTML:
return HTML.without_escaping(t)
func escape_int(i:Int)->HTML:
func escape_int(i:Int->HTML):
return HTML.without_escaping("$i")
func paragraph(content:HTML)->HTML:
func paragraph(content:HTML->HTML):
return $HTML"<p>$content</p>"
func main():

View File

@ -1,47 +1,47 @@
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)
func minus(a,b:Vec2; inline)->Vec2:
func minus(a,b:Vec2 -> Vec2; inline):
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
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)
func times(a,b:Vec2; inline)->Vec2:
func times(a,b:Vec2 -> Vec2; inline):
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)
func negative(v:Vec2; inline)->Vec2:
func negative(v:Vec2 -> Vec2; inline):
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)
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)
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)
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)
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)
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)
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)
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)
func main():

View File

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

View File

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

View File

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

View File

@ -1138,6 +1138,15 @@ type_t *get_type(env_t *env, ast_t *ast)
if (ret->tag == AbortType)
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))
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));

View File

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