triforce

所属分类:编程语言基础
开发工具:Swift
文件大小:0KB
下载次数:0
上传日期:2024-02-18 19:00:16
上 传 者sh-1993
说明:  Triforce编程语言
(Triforce programming language)

文件列表:
compiler/
examples/
img/
lib/
st4/
.editorconfig
CONTRIBUTING.md
thinking_list.md

# Triforce programming language ![banner](https://github.com/TropicSapling/triforce/blob/master/img/banner.PNG) ## This README is (very) outdated **See [random_experiments.tri](https://github.com/TropicSapling/triforce/blob/master/examples/random_experiments.tri) for sketches of newer language concepts.** - **Also see [SPEC.tri](https://github.com/TropicSapling/triforce/blob/master/examples/SPEC.tri) for a very incomplete specification** *Everything below this point was last updated on 2020-08-05.* ## About Triforce is a programming language emphasizing performance, power and productivity. The main goals of the language include: - a consistent, sensible and well-thought-out language design - a small, generalised and extensible core language, including support for powerful macro-like functions - an advanced type system, including dependent types - the ability to both work on a high level and a lower level close to hardware - safety by default; less safe options will be discouraged and require opt-in - readable, understandable code (at least for common situations) - more things yet to be figured out... Obviously, some compromises are going to have to be made in order to achieve these goals. The compilation process is probably going to be rather slow, for example. ### A word on the name The language has recently been renamed from P+ to Triforce, meaning some things are still using the old name or file extension. There are also some (minor?) problems with the name, see issue [#308](https://github.com/TropicSapling/triforce/blob/master/https://github.com/TropicSapling/triforce/issues/308). ### Learning the language I'm currently working on a wiki for this language which will explain some things about the language in a more understandable way than this README does. The wiki is currently very incomplete however, so you can't really learn much from it yet. But it's not really a good idea to start learning this language at this moment anyway, since there's not much stability right now and the latest working compiler is not even able to compile more than a small subset of an old version of the language. ### Syntax highlighting Currently, there is only syntax highlighting available for Sublime Text 3, which can be found in [the st3 folder.](https://github.com/TropicSapling/triforce/blob/master//st3) If you don't feel like using ST3, you can either try creating your own syntax highlighting for the language, or try using the Swift highlighting (which is, well, better than nothing). ### Some quick info before you start reading the rest Currently, this README pretty much only consists of a language specification. Similarly to most language specifications, it's rather hard to understand and you'll probably have a hard time learning the language by reading it. It also has the extra perk of not even being written well enough to precisely describe the language! And did I mention that I'm also changing it all the time? Really, the specification is just here for the developers to remember everything. But, you can always attempt to read the rest anyway if you want xD ## Spec #### Definitions Keywords surrounded by * brackets (`[]`) are *optional* * angle brackets (`<>`) **must** be replaced by a name of your choice * backticks (`` ` ``) are **required** and escapes these definitions (i.e. `` {a`|`b} `` means you must literally type `{a|b}`) * braces (`{}`) **and** seperated by bars (`|`) are part of a list of mutually exclusive **required** keywords * brackets (`[]`) **and** seperated by bars (`|`) are part of a list of mutually exclusive *optional* keywords The equivalence symbol (`<=>`) means essentially what it does in mathematics. `<...>` and `[...]` mean something **required** respectively *optional* that fits in. ``` \` ``` escapes the escaper (i.e. ``` \`\` ``` means you must literally type ``` `` ```). Everything else is **required.** -------- **NOTE:** This specification mainly specifies the built-in parts of the language. See the prelude and libraries for the rest. -------- ### Programs 1. The compiler will evaluate programs as much as it can during compilation, and then convert the remnants into a specified output format. - Normally this is machine code 2. Programs are composed as described under "Program composition". -------- ### Program composition ```XML = = [raw] { | {|} [] [...] | | unparsed | parsed } = {[] | ([]) | (([])) | <...>} = [...] = [impure|unpredictable] [...] => = $() as = { | } [...] = [implicitly] [unparsed] [raw] [impure|unpredictable] [returning ] [...] [constructed using ] = { | | ${|#} | #()} [...] = {0|1|2|3|4|5|6|7|8|9}[...] ``` **Note:** An `` may evaluate at compile time to a valid, say, ``, and would in such a case be a valid ``. See "Anonymous functions" §9. Syntax sugar changes things a bit too; see "Syntax sugar". -------- ### Literals 1. Number structure: `{0|1|2|3|4|5|6|7|8|9}[0|1|2|3|4|5|6|7|8|9|_|.][...]` - `.` is a comma used for fractions - `_` is a separator used to improve readability - ex: `1_234_567.89` 2. Numbers prefixed with `0x` are hexadecimal and additionally allow `a`, `b`, `c`, `d`, `e` and `f`. - ex: `0x123456789abc` 3. Numbers prefixed with `0o` are octal and exclude `8` and `9`. - ex: `0o1234567` 4. Numbers prefixed with `0b` are binary and only allow `0`, `1` and `_`. - ex: `0b00101001_00000110_01010110_10010010` 5. See "Low level" for low level forms of number literals. 6. The symblock `__sb_default_str__` is used for string literals. - syntax declared in the prelude: `decl symblock __sb_default_str__ enclosed by " " with escaper \;` - `\n`, `\r`, `\t`, `\0` and `\\` inside of a string mean "newline", "carriage return", "tab", "null" and "backslash" respectively ### Anonymous functions ![section banner](https://github.com/TropicSapling/triforce/blob/master/img/sections/anon_funcs.PNG) 1. Structure: `( => ) `. 2. `` = `() [()] [...]` 3. `` = ` [] [...]` 4. Every parameter is a *pattern def*. 5. All functions are closures (capturing their original environment). 6. An empty `` is equivalent to `paused __caller_scope__`. 7. If not enough input args are given, the function is partially applied. 8. Once fully applied, functions reduce to `` (with all `` defined). - This is what it means to say that a function returns `` 9. Functions and patterns can be (partially) called/applied inside of ``, ``, `` and ``. - Note that surrounding backticks (`` \`\` ``) are necessary when applying inside `` - i.e. if we `let f = Something`, then `let f _ = SomethingElse` redefines `f` while `` let `f _` = SomethingElse `` becomes `let Something = SomethingElse` - this is because `` is taken as `implicitly unchecked paused` - the surrounding backticks escape all implicits, thereby forcing evaluation even when implicitly `paused` - `` is always fully evaluated, even if it's inside a `paused` block 10. Functions are *pure* and *checked* by default. - A pure function has the following properties: - its return value is the same for the same input - note that the input consists of both the arguments passed and the state of the outer scope - its evaluation has no side effects - note that debug-mode side effects disappearing in release-mode don't count, allowing i.e. `##[dbg_mode_only] debug <...>` (?) - The body of a checked function will be checked by the compiler as soon as it is encountered - this means undefined patterns, incorrect syntax, mismatches, etc. are not allowed 11. `impure ` allows a function to have side effects. 12. `unpredictable ` allows a function to have side effects and different return values for the same input. - Mainly useful for functions interacting with the outer world (user input, true randomness, etc.) 13. `unchecked ` allows for an expression (i.e. a function) to be non-checked. - This means the compiler won't check the expression until it's in its final scope - For an example, see "Example code snippets" §2 14. While functions require at least 1 parameter, `(_ as ()) => ` can be used to emulate a function without parameters. - This is also the recommended way; doing `(_ as ...)` or `(_ as _)` serves different (rare) purposes -------- ### Patterns (variables but better) ![section banner](https://github.com/TropicSapling/triforce/blob/master/img/sections/patterns.PNG) 1. `` = `($() as [constructed using ])` where - `` = ` [{()|}] [...] []` where - ``, `dname continuation`, `` are allowed to contain any symbols, including whitespace (TODO: exception for ops) - `` = `[] [{()||${|#}|#}] [...] []` where - ``, `mname continuation`, `` are allowed to contain any symbols, including whitespace (TODO: exception for ops) - `$` is either: - a name for a parameter that is linked to a parameter of the same name in ``, or - the symbol `_` (specifying to link whatever parameter is left to link) - `` is a number specifying what parameter to link to - ex: `(($(add (1) and (2) to ($(a) as 3) plus $b) as $#1 $a $#0 $_) => <...>) ($x $y $z $w => x + y + z + w)` where - `<...>` = `add 1 and 2 to 3 plus 4` => `($x $y $z $w => x + y + z + w) 2 3 1 4` => `2 + 3 + 1 + 4` - if we `let f = $x $y $z => <...>` then `$a as f #_ #_` <=> `$a as f _ _` - **note:** this equivalence does not hold for `$a as paused f #_ #_ #_` and `$a as paused f _ _ _` - for more info on `#`, see "Example code snippets" §4 - `` is like `` except `#` is not allowed and it works a bit differently - i.e. if `Player $health $max_health` is defined, then `Player 50 100 constructed using $constructor` defines `$constructor` as `Player` - `Player 50 100 constructed using Player $a $b` also works, but defines nothing - patterns named `_` (written like `($_ as <...>)`) are called unnamed patterns and will not be defined 2. Call structure for ex. def. `$(example pattern taking (_ as _) and (_ as _)) as _`: - mixfix ex: `example pattern taking (x) and (123)` - prefix ex: `(example pattern taking $_ and $_) x 123` - `$_` is here used as an unnamed pattern since `_` 3. Patterns are defined within the scope described by the *pattern parsing algorithm*. 4. Patterns can only be defined within ``. - If it looks like a pattern is defined outside, it's actually a partially applied pattern 5. Patterns, like functions, can be partially applied. - This can be done by leaving out some of the `` or by having placeholders for args using `$()` - `` has the same syntax as ``, but doesn't define the pattern - Given a defined pattern `$($a f $b $c)`: - ex. of leaving out args: `f`, `1 f`, `f 2`, `1 f 2` - ex. of having placeholders: `$x f $y $z`, `1 f $y $z`, `$x f 2 $z`, `$x f $y 3`, `1 f $y 3` - ex. of both: `1 f $y 3` 6. Patterns only consisting of names are called *variables*. - This means variables are a subset of patterns in Triforce - Whenever we talk about patterns, we're including variables - I.e. `$(example pattern)` is a variable, while `$(example pattern taking $x)` is not 7. Patterns can be placed anywhere functions can as long as they become a function after full evaluation. - This means that anywhere it says `` in this README it's actually `` - TODO: check if there are any exceptions to this -------- ### Pattern parsing algorithm 1. Choose a `$(<...>)` and move to its outside. - NOTE: If the pattern is after 'as', choose a `#(<...>)` here instead (? TODO) 2. If inside another `$(<...>)`, move to its outside, and then keep leaving scopes until you find `as`. If not, keep leaving scopes until you find `=>`. 3. Your pattern is defined after this `as` or `=>`. -------- ### Pattern matching ![section banner](https://github.com/TropicSapling/triforce/blob/master/img/sections/pattern_matching.PNG) 1. When a pattern name is used, the compiler will try to find a matching pattern definition. If it can't find any match, it reports a compile time error. 2. If 2 or more variables in the same function have the same name they will be pattern matched to be equal. - i.e. in `$x $y $x => <...>` the 2 `x`s must be equal - the equality function `==` is defined using this 3. An and/or-pattern, `a|b|...|z [& ] [...]`, can be used in pattern matching. - `a|b|c` <=> `a|a|b|c|b|a` <=> `c|a|b` - `a`, `b`, `c`, `a|b`, `a|c` and `a|b|c` all match `a|b|c` - `a|b|c`, `a|b` and `a|c` *may* match `a`, `b` or `c` (and `a|b|c` *may* match `a|b`) - by default this will compile and instead pattern matching will be completed at runtime; if this fails, the program crashes - if using `prerun` this counts as failing to match and won't compile - `a|b|c & b|c|d` <=> `b|c` - all matching involving and-patterns is done after the and-patterns have collapsed into or-patterns - and/or-patterns may contain the "not" (exclusion) operator `~` - ex: `a|b|c & ~c` <=> `a|b` - ex: `a|b & ~c` <=> `a|b` - **note:** ` & ~Undefined` is *not* equivalent to ``, see "Pattern matching" §6 - side-note: and/or-patterns are similar to intersection/union types in other languages - or-patterns are *lazy* 4. `...` is used in (and/or-)patterns to let the compiler figure out the rest. - ex: `0|1|...` is an or-pattern consisting of all integers >= 0 5. Pattern matching is done at compile time whenever possible. If pattern matching can't be completed during compile time, it will continue during runtime. - `prerun` can be used to override this and force pattern matching to be completed during compile time - `run` can be used to override this and force pattern matching to only be done during runtime 6. The special `Undefined` value matches any pattern. - i.e. `$x as 123` <=> `$x as Undefined|123` - note that while this will compile, if `x` is `Undefined` but still used during runtime the program will crash - `$x as Undefined` specifies that `x` must be `Undefined` - useful for expressions returning an infinite loop: `forever {<...>}: Undefined` - `$x as ~Undefined` overrides this and specifies that `x` must *not* be `Undefined` - useful for ensuring something is total: `this_should_be_total: ~Undefined` -------- ### Values ![section banner](https://github.com/TropicSapling/triforce/blob/master/img/sections/values.PNG) 1. Partially applied functions and patterns are treated as values. - called *objects* when of the form ` [] ()` 2. There exists a special `Undefined` value, which will be inserted into compilation or-patterns whenever a value might not come to exist during runtime. This happens if: - the program specifies it might crash during runtime - ex: `let x = rand any Int; if x == 1337 {panic!}; x` returns `Undefined|(any Int)` during compilation - the compiler suspects there is an infinite loop in the program - ex: `let x: auto = 0; forever {x++}; x` returns `Undefined|1|2|...` during compilation - note that due to the halting problem the compiler may think there is an infinite loop when there isn't, hence 'suspects' - for more info, see "Example code snippets" §1 3. There are no other values. - Numbers, strings, etc. are defined as partially applied functions or patterns 4. Values are differentiated using pattern matching (as described under "Patterns" and "Pattern matching"). -------- ### Pseudo-values ![section banner](https://github.com/TropicSapling/triforce/blob/master/img/sections/pseudo_values.PNG) 1. Pseudo-values are similar to values but act a bit differently, and include: - and/or-patterns - ex: `1|2|3 & 2|3|4` - values and 1-value ("singleton") and/or-patterns are equivalent - ex: `456` is both a value and a 1-value and/or-pattern - placeholder-values - ex: `$x` (outside of pattern definition) 2. Pseudo-values may be created by the programmer and/or the compiler. - programmer ex: - or-patterns: `random value in range 0|1|...` - placeholder-values: `$n+1` - compiler ex: - or-patterns: creates an or-pattern for what `(123|456|789) + 1` returns: `124|457|790` - placeholder-values: inserts missing placeholder in `+1` by converting to `$n+1` 3. Pseudo-values can be placed anywhere values can (if in the right situation). 4. Pseudo-values only exist before runtime (during compilation). - and-patterns collapse into or-patterns during compilation - i.e. `1|2|3 & 2|3|4` collapses into `2|3` - **note:** ` & ~Undefined` is an exception to this, see "Pattern matching" §6 - or-patterns (eventually) collapse into single values at runtime - i.e. `1|2` collapses into either `1` or `2` - programs not allowing this to happen won't be accepted by the compiler (TODO: check if this works, maybe change to runtime crash?) - placeholder-values are converted into something else at runtime (TODO: figure out what) 5. And/Or-patterns are further described in "Pattern matching" §3 6. Placeholder-values are further described in "Patterns" §5 -------- ### Evaluation 1. Triforce uses eager evaluation. 2. `()` returns whatever is left of `` after evaluation to the outer scope. 3. The compiler will try to run as much as possible during compilation unless otherwise specified. 4. There are 3 stages of evaluation: 1. Patterns are "expanded" - i.e. if we `let f = $x $y => <...>` then `f` is expanded to `f $x $y` 2. Synonyms are deconstructed (see "Synonyms and Shadows") 3. Function application is evaluated 5. `paused` prevents evaluation from going past stage 1. -------- ### Equality ![section banner](https://github.com/TropicSapling/triforce/blob/master/img/sections/equality.PNG) 1. 2 finally evaluated values are equal if they refer to the same named function and they have the same applied args. - This means anonymous functions are incomparable - A value is first finally evaluated when all synonyms have been deconstructed - What it means for them to "refer" to the same function is that they are both partial applications of the exact same function - See "Example code snippets" §5 for more info 2. 2 placeholder-values are always equal. - I.e. `$xyz == $abc` 3. `$x $y => ` and `$x => $y => ` are always equal. - Note that this equality doesn't hold if `$y => ` is named though 4. Equality of and-patterns is decided after they have collapsed into or-patterns. 5. Equality of or-patterns is either decided after collapse at runtime, *or* during compilation iff all below criteria are met: - They consist of the same values in the same order - They were both formed as a result of known-to-be-equal pseudo-values being combined in some way with *known* terms (see "Misc" §8) 6. 2 values being equal and 2 values matching are related but not the same, see "Pattern matching" §2 7. Comparison involving `paused` values will compare the values as if they were strings. 8. See "Example code snippets" §1 for an example of equality. -------- ### Synonyms and Shadows ... ...

近期下载者

相关文件


收藏者