Added UFCS

This commit is contained in:
2023-02-14 19:59:01 +11:00
committed by GitHub
parent e470dc21ff
commit bf890ac845
6 changed files with 39 additions and 44 deletions

View File

@@ -17,7 +17,7 @@ The header consists of four values:
The first three are single unsigned bytes, embedded at the beginning of the bytecode in sequence. These represent the major, minor and patch versions of the language. The fourth value is a null-terminated string of unspecified data, which is *intended* but not required to specify the time that the langauge's compiler was itself compiled. The build string can also hold arbitrary data, such as the current maintainer's name, current fork of the language, or other versioning info.
There are some strict rules when interpreting these values (mimicking, but not conforming to semver.org):
There are some strict rules when interpreting these values (mimicking, but not conforming to [semver.org](https://semver.org/)):
* Under no circumstance, should you ever run bytecode whose major version is different - there are definitely broken APIs involved.
* Under no circumstance, should you ever run bytecode whose minor version is above the interpreter's minor version - the bytecode could potentially use unimplemented features.

View File

@@ -85,27 +85,27 @@ fn combine(...rest) {
print combine(1, 2, 3);
```
## Dot Notation and Global Functions
## UFCS and Global Functions
Any function that begins with an underscore can be called using the dot notation, which is syntactic sugar:
Functions can be called using the universal function call syntax, which is just syntactic sugar for a normal function call:
```
fn _printMe(self) {
fn printMe(self) {
print self;
}
array.printMe();
```
There are several underscore functions provided by default:
There are several globally available functions provided by default:
```
_set(self, key, value) //array, dictionary
_get(self, key) //array, dictionary
_push(self, value) //array
_pop(self) //array
_length(self) //array, dictionary, string
_clear(self) //array, dictionary
set(self, key, value) //array, dictionary
get(self, key) //array, dictionary
push(self, value) //array
pop(self) //array
length(self) //array, dictionary, string
clear(self) //array, dictionary
```
## Slice Notation

View File

@@ -10,10 +10,6 @@ To that end, I've begun working on this: [Airport Game](https://github.com/Ratst
This is a simple game concept, which I can implement within a reasonable amount of time, before extracting parts to create the engine proper. It feels almost like a mobile game, so I'm hoping this engine will be runnable on android (though at the time of writing, I've yet to investigate how).
## Bugfixes
This is probably the easiest goal to accomplish, but also the least urgent. The [issue tracker](https://github.com/Ratstail91/Toy/issues) provides a list of known bugs and issues that need to be addressed, but for the time being, my attention is focused elsewhere.
## New Features I'd Like One Day
Some things I'd like to add in the future include:
@@ -26,7 +22,7 @@ Some things I'd like to add in the future include:
* Multiple return values from functions
* ~~Ternary operator~~
* interpolated strings
* MSVC compilation
* ~~MSVC compilation~~
Some of these have always been planned, but were sidelined or are incomplete for one reason or another.

View File

@@ -63,23 +63,23 @@ This function does a lot of work:
Note: This function resembles `loadScript()`, but skips the compilation step.
## _runScript(self: opaque)
## runScript(self: opaque)
This function executes an external script, which must first be loaded into an opaque variable with either `loadScript()` or `loadScriptBytecode()`.
## _getScriptVar(self: opaque, name: string)
## getScriptVar(self: opaque, name: string)
This function retrieves a variable from the top level of a script's environment.
## _callScriptFn(self: opaque, name: string, ...rest)
## callScriptFn(self: opaque, name: string, ...rest)
This function retrieves a function from the top level of a script's environment, and calls it with `rest` as the argument list.
## _resetScript(self: opaque)
## resetScript(self: opaque)
This function resets the script so that it is no longer in a "dirty" state, and can be re-run using `_runScript()`.
This function resets the script so that it is no longer in a "dirty" state, and can be re-run using `runScript()`.
## _freeScript(self: opaque)
## freeScript(self: opaque)
This function frees a script's resources, cleaning up any memory that is no longer needed. Failing to call this will result in a memory leak.

View File

@@ -12,23 +12,23 @@ import standard;
This function returns a string representation of the current timestamp.
## _concat(self, other)
## concat(self, other)
This function only works when self and other are matching compounds (both arrays, dictionaries or strings). It returns a new compound of that kind, with the content of `other` appended to the content of `self`.
## _containsKey(self: dictionary, key)
## containsKey(self: dictionary, key)
This function returns `true` if `self` contains the given `key`, otherwise it returns false.
## _containsValue(self, value)
## containsValue(self, value)
This function returns `true` if `self` contains the given `value`, otherwise it returns false.
## _every(self, func: fn)
## every(self, func: fn)
This function takes either an array or a dictionary as the `self` argument, and a function as `func`. The argument `func` must take two arguments - the first is the index/key of the array/dictionary, and the second is the value. The contents of `self` are passed into `func`, one element at a time, until `func` returns `false`, at which point this function returns `false`. Otherwise this function returns `true`.
## _forEach(self, func: fn)
## forEach(self, func: fn)
This function takes either an array or a dictionary as the `self` argument, and a function as `func`. The argument `func` must take two arguments - the first is the index/key of the array/dictionary, and the second is the value. The contents of `self` are passed into `func`, one element at a time.
@@ -44,23 +44,23 @@ var a = [1, 3, 5];
a.forEach(p); //prints 1, 3, and 5 to stdout
```
## _filter(self, func: fn)
## filter(self, func: fn)
This function takes either an array or a dictionary as the `self` argument, and a function as `func`. The argument `func` must take two arguments - the first is the index/key of the array/dictionary, and the second is the value. The contents of `self` are passed into `func`, one element at a time, and the function returns a new compound for every element that `func` returned a truthy value for.
## _getKeys(self: dictionary)
## getKeys(self: dictionary)
This returns an array of all non-null keys stored within the dictionary. The order is undefined.
## _getValues(self: dictionary)
## getValues(self: dictionary)
This returns an array of all values with non-null keys stored within the dictionary. The order is undefined.
## _indexOf(self: array, value)
## indexOf(self: array, value)
This function returns the first index within `self` that is equal to `value`, or `null` if none are found.
## _map(self, func: fn)
## map(self, func: fn)
This function takes either an array or a dictionary as the `self` argument, and a function as `func`. The argument `func` must take two arguments - the first is the index/key of the array/dictionary, and the second is the value. It returns an array with the results of each call - the order of the results when called on a dictionary are undefined.
@@ -76,7 +76,7 @@ var a = [1, 2, 3];
print a.map(increment); //prints [2,3,4];
```
## _reduce(self, default, func: fn)
## reduce(self, default, func: fn)
This function takes either an array or a dictionary as the `self` argument, a default value, and a function as `func`. The argument `func` takes three arguments - the first is the accumulator, the second is the index/key and the third is the value. It applies the given function to every element of the array/dictionary, passing the result of each call as the accumulator to the next (the default value is used for the first call). Finally, the final value of the accumulator is returned to the caller.
@@ -92,11 +92,11 @@ var a = [1, 2, 3, 4];
print a.reduce(0, f); //prints "10"
```
## _some(self, func: fn)
## some(self, func: fn)
This function takes either an array or a dictionary as the `self` argument, and a function as `func`. The argument `func` must take two arguments - the first is the index/key of the array/dictionary, and the second is the value. The contents of `self` are passed into `func`, one element at a time, until `func` returns `true`, at which point this function returns `true`. Otherwise this function returns `false`.
## _sort(self: array, func: fn)
## sort(self: array, func: fn)
This function takes an array as the `self` argument, and a comparison function as `func`. The argument `func` must take two arguments, and return a truthy or falsy value. The contents of the array in `self` are sorted based on the results of `func`, as though function were the less comparison function.
@@ -107,26 +107,26 @@ fn less(a, b) {
return a < b;
}
var a = [4, 2, 3, 1];
var a = [4, 1, 3, 2];
print a.sort(less); //prints "[1, 2, 3, 4]"
```
## _toLower(self: string)
## toLower(self: string)
This function returns a new string which is identical to the string `self`, except any uppercase letters are replaced with the corresponding lowercase letters.
## _toString(self)
## toString(self)
This function returns a string representation of `self`. This is intended for arrays and dictionaries, but can theoretically work on any printable value.
If the resulting string is longer than `TOY_MAX_STRING_LENGTH` - 1, then it is truncated.
## _toUpper(self: string)
## toUpper(self: string)
This function returns a new string which is identical to the string `self`, except any lowercase letters are replaced with the corresponding uppercase letters.
## _trim(self: string, trimChars: string = " \t\n\r")
## trim(self: string, trimChars: string = " \t\n\r")
This function returns a new string which is identical to the string `self`, except any characters at the beginning or end of `self` which are present in the argument `trimChars` are removed. The argument `trimChars` is optional, and has the following characters as the default value:
@@ -137,11 +137,11 @@ This function returns a new string which is identical to the string `self`, exce
These characters used because they are the only control characters currently supported by Toy.
## _trimBegin(self: string, trimChars: string = " \t\n\r")
## trimBegin(self: string, trimChars: string = " \t\n\r")
This is identical to `_trim(self, trimChars)`, except it is only applied to the beginning of the first argument.
## _trimEnd(self: string, trimChars: string = " \t\n\r")
## trimEnd(self: string, trimChars: string = " \t\n\r")
This is identical to `_trim(self, trimChars)`, except it is only applied to the end of the first argument.

View File

@@ -4,5 +4,4 @@ Toy uses GitHub CI for comprehensive automated testing - however, all of the tes
The tests consist of a number of different situations and edge cases which have been discovered, and should probably be thoroughly tested one way or another. There are also several "-bugfix.toy" scripts which explicitly test a bug that has been encountered in one way or another. The libs that are stored in `repl/` are also tested - their tests are under `/tests/scripts/lib`; some error cases are also checked by the mustfail tests in `/test/scripts/mustfail`.
Finally, GitHub CI has access to the option `make test-sanitized` which attempts to use memory sanitation. I don't know enough about this to offer much comentary, only that several invisible issues are monitored this way.
GitHub CI also has access to the option `make test-sanitized` which attempts to use memory sanitation. I don't know enough about this to offer much comentary, only that several invisible issues are monitored this way.