Commit 30cbaf92 authored by Andre Lipke's avatar Andre Lipke

Initial commit

parents
# Files and directories created by pub
.packages
.pub/
build/
# Remove the following pattern if you wish to check in your lock file
pubspec.lock
# Directory created by dartdoc
doc/api/
<component name="libraryTable">
<library name="Dart SDK">
<CLASSES>
<root url="file:///usr/lib/dart/lib/async" />
<root url="file:///usr/lib/dart/lib/collection" />
<root url="file:///usr/lib/dart/lib/convert" />
<root url="file:///usr/lib/dart/lib/core" />
<root url="file:///usr/lib/dart/lib/developer" />
<root url="file:///usr/lib/dart/lib/html" />
<root url="file:///usr/lib/dart/lib/indexed_db" />
<root url="file:///usr/lib/dart/lib/io" />
<root url="file:///usr/lib/dart/lib/isolate" />
<root url="file:///usr/lib/dart/lib/js" />
<root url="file:///usr/lib/dart/lib/js_util" />
<root url="file:///usr/lib/dart/lib/math" />
<root url="file:///usr/lib/dart/lib/mirrors" />
<root url="file:///usr/lib/dart/lib/svg" />
<root url="file:///usr/lib/dart/lib/typed_data" />
<root url="file:///usr/lib/dart/lib/web_audio" />
<root url="file:///usr/lib/dart/lib/web_gl" />
<root url="file:///usr/lib/dart/lib/web_sql" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/llama.iml" filepath="$PROJECT_DIR$/llama.iml" />
</modules>
</component>
</project>
\ No newline at end of file
This diff is collapsed.
# Changelog
## 0.0.1
- Initial version, created by Stagehand
Copyright (c) 2017, pixel.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Llama
Llama is a language that compiles directly to lambda calculus with almost no layer of abstraction
Variable names follow the regex `[A-Za-z_][A-Za-z0-9_]*`
#### Expression
Expressions are one of anything below, Long expressions (the body of a llama for example) consume multiple expressions until they hit the EOF or some token like `)`
#### LLama
Llamas work the same as lambdas in lambda calculus<br/>
`λx.λy.λz.x` looks like `\x\y\z x` in llama<br/>
syntax: `\name lexpr`
#### Application
Applications work the same as usual, two expressions grouped together is an application<br/>
It is always left associative meaning `a b c d` = `((a b) c) d`<br/>
syntax: `expr expr`
#### Variables
Variables are bound to the closest llama that matches their name, otherwise they are free and applications to it cannot be solved.<br/>
Binding should work exactly like it would in a high level programming language like Dart, where variables are bound based on where they were the application took place, not where it was subsituted into.<br/>
syntax: `name`
#### Parentheses
Parentheses allow you to group expressions together to explicitly control application order<br/>
example: `a (b c)`<br/>
syntax: `(lexpr)`
#### Comments
Comments start with `//` and continue until the end of line<br/>
example:
```
~\flutter 1 // The one
```
#### Squiggly
The squiggly character is like parentheses that dont need to be closed<br/>
example: `\f\x f(f(f(f x)))` = `\f\x f~f~f~f x`<br/>
syntax: `~lexpr`
#### Definitions
This is the first major difference to lambda calculus, you can procedurally define variables to be used in code preceding it<br/>
Only valid inside of a long expression<br/>
example:`~\a 1 ~\b (succ a) ~\b (succ b) b` = `3` (succ not included by default)<br/>
syntax: `~\name expr lexpr`<br/>
The way this works is it puts the lexpr as a body of a llama and applies your expr to it
```
~\a 1
~\b succ a
succ b
```
turns into
```
(\a
(\b
succ b
) succ a
) 1
```
#### Vectors
Vectors can be created using square brackets<br/>
example: `[1 2 3]` = `\f\x f 1~f 2~f 3 x`<br/>
syntax: `[expr...]`
#### Numbers
Numbers use basic church encoding so `1` means `\f\x f x` and `3` means `\f\x f~f~f x`<br/>
example:
```
123 // decimal
0x7B // hex
0b1111011 // binary
0o173 // octal
'{' // character
```
#### Strings
String literals are equivalent to a vector of char codes<br/>
Both character literals and strings support the common escapes `\a \b \f \n \r \t \v \\ \"` and also number escapes `\123 \x7b \b1111011`<br/>
example: `"foo"` = `['f' 'o' 'o']`<br/>
#### Llama include
Used to include a whole file as a llama, the file must have a main body</br>
syntax: `~"filename"`<br/>
example:
######foo.lm
```
succ 1
```
######bar.lm
```
succ \"foo.lm" // result is 3
```
#### Definition include
Unlike llama includes, definition includes import definitions and the file cannot have a main body<br/>
syntax: `~\"filename"`<br/>
example:
###### foo.lm
```
~\concat(\a\b
\f\x a f ~b f x
)
```
###### bar.lm
```
~\"foo.lm"
concat "foo" "bar" // result is "foobar"
```
\ No newline at end of file
analyzer:
strong-mode: true
# exclude:
# - path/to/excluded/files/**
# Lint rules and documentation, see http://dart-lang.github.io/linter/lints
linter:
rules:
- cancel_subscriptions
- close_sinks
- hash_and_equals
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- test_types_in_equals
- unrelated_type_equality_checks
- valid_regexps
~\"stdlib.lf"
~\getjmp (\code
vFold (vIndexify code) (tTuple 3 [] [] []) (\jt\e
~\i (e tFirst)
~\char (e tSecond)
if (iIsEQ char '[') (
~\st (jt (tGet 3 0))
~\jt (tSet 3 jt 0 (vInsertEnd st i))
jt
)~if (iIsEQ char ']') (
~\st (jt (tGet 3 0))
~\ste (vLast st null)
~\jmpFwd (jt (tGet 3 1))
~\jmpBack (jt (tGet 3 2))
~\jt (tSet 3 jt 0 (vRemoveLast st))
~\jt (tSet 3 jt 1 (vInsertEnd jmpFwd~tPair ste i))
~\jt (tSet 3 jt 2 (vInsertEnd jmpBack~tPair i~iSucc ste))
jt
) jt
)
)
(\code\input
~\jmp (getjmp code)
~\jmpFwd (jmp (tGet 3 1))
~\jmpBack (jmp (tGet 3 2))
~\indexMap (\v\i
(vFirstWhere v (\e iIsEq (e tFirst) i) 0) tSecond
)
~\codeLength (vLength code)
~\pc (tGet 5 0)
~\setPc (\st\v tSet st 5 0 v)
~\ptr (tGet 5 1)
~\setPtr (\st\v tSet st 5 1 v)
~\mem (tGet 5 2)
~\setMem (\st\v tSet st 5 2 v)
~\out (tGet 5 3)
~\setOut (\st\v tSet st 5 3 v)
~\inputIndex (tGet 5 4)
~\setInputIndex (\st\v tSet st 5 4 v)
~\byteSucc (\n
(iIsEQ n 255) 0 (iSucc n)
)
~\bytePred (\n
(iIsEQ n 0) 255 (iPred n)
)
(while (tTuple 5
0 // pc
0 // ptr
[0] // mem
[] // out
0 // inputIndex
) (\st iIsLT (st pc) codeLength) (\st
~\st (
~\inst (vGet code (st pc) null)
if (iIsEQ inst '>') (
~\st (setPtr st (iSucc~st ptr))
(if (iIsEQ (st ptr) (vLength~st mem))
return setMem st~vInsertEnd (st mem) 0
) (return st)
)~if (iIsEQ inst '<') (
if (iIsZero~st ptr) (
return setMem st~vInsertStart (st mem) 0
) (
return setPtr st~iPred~st ptr
)
)~if (iIsEQ inst '+') (
return setMem st~vSet (st mem) (st ptr)~byteSucc~vGet (st mem) (st ptr) null
)~if (iIsEQ inst '-') (
return setMem st~vSet (st mem) (st ptr)~bytePred~vGet (st mem) (st ptr) null
)~if (iIsEQ inst '[') (
if (iIsZero~vGet (st mem) (st ptr) 0) (
return setPc st~indexMap jmpFwd (st pc)
) (
return st
)
)~if (iIsEQ inst ']') (
return setPc st~indexMap jmpBack (st pc)
)~if (iIsEQ inst ',') (
~\st (setMem st~vSet (st mem) (st ptr)~vGet input (st inputIndex) 0)
return setInputIndex st~iSucc~st inputIndex
)~if (iIsEQ inst '.') (
setOut st~vInsertEnd (st out)~vGet (st mem) (st ptr) 0
) st
)
return setPc st~iSucc (st pc)
)) out
)"." ""
\ No newline at end of file
// Copyright (c) 2017, Andre Lipke. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.
import 'dart:io';
import 'package:lambdafuck/llama.dart';
main(List<String> arguments) async {
try {
var parser = new Parser();
var expr = parser.parseFile(new File("bf.lf"));
//var expr = parser.parse("main", '["a" "s" "d" "f"]');
print(expr);
expr.bind();
var solver = new TrashSolver(expr);
solver.solve();
print(solver.expr);
} on ParserError catch (e) {
print("${e.where.chunkname}:${e.where.pos} : ${e.error}");
return null;
}
}
// Copyright (c) 2017, pixel. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:isolate';
import 'package:lambdafuck/llama.dart';
import 'package:worker/worker.dart';
const Map<String, String> tests = const {
'while 0 (\\i iIsNEQ (iMul i 2) 8) (\\i iSucc i)': '4',
'[(true 1 2) (false 1 2)]': '[1 2]',
'[(bNot false) (bNot true)]': '[true false]',
'[(bAnd false false) (bAnd false true) (bAnd true false) (bAnd true true)]': '[false false false true]',
'[(bOr false false) (bOr false true) (bOr true false) (bOr true true)]': '[false true true true]',
'[(bXor false false) (bXor false true) (bXor true false) (bXor true true)]': '[false true true false]',
'[(iSucc 0) (iSucc 7)]': '[1 8]',
'[(iPred 0) (iPred 1) (iPred 8)]': '[0 0 7]',
'[(iAdd 0 0) (iAdd 0 5) (iAdd 6 9)]': '[0 5 15]',
'[(iSub 0 0) (iSub 0 5) (iSub 13 6)]': '[0 0 7]',
'[(iMul 0 0) (iMul 1 7) (iMul 20 21)]': '[0 7 420]',
//'[(iDiv 0 0) (iDiv 1 7) (iDiv 10 2)]': '[0 0 5]',
'[(iPow 0 0) (iPow 2 8) (iPow 10 3)]': '[1 256 1000]',
'[(iIsZero 0) (iIsZero 1) (iIsZero 2)]': '[true false false]',
'[(iIsEQ 0 0) (iIsEQ 1 2) (iIsEQ 3 3)]': '[true false true]',
'[(iIsNEQ 0 0) (iIsNEQ 1 2) (iIsNEQ 3 3)]': '[false true false]',
'[(iIsGT 0 0) (iIsGT 6 9) (iIsGT 9 6)]': '[false false true]',
'[(iIsLT 0 0) (iIsLT 6 9) (iIsLT 9 6)]': '[false true false]',
'[(iIsGE 0 0) (iIsGE 6 9) (iIsGE 9 6)]': '[true false true]',
'[(iIsLE 0 0) (iIsLE 6 9) (iIsLE 9 6)]': '[true true false]',
'[(tTuple 4 a b c d) (tTuple 2 a b) (tTuple 0)]': '[<a b c d> <a b> <>]',
'[(tVector 0 <>) (tVector 1 <a>) (tVector 3 <a b c>)]': '[[] [a] [a b c]]',
'[\n'
'(tGet 4 0 a b c d)\n'
'(tGet 3 2 a b c)\n'
'(tGet 1 0 a)\n'
']' : '[a c a]',
'[\n'
'(tVararg 4 (\\v v) a b c d)\n'
'(tVararg 0 (\\v v))\n'
'(tVararg 3 (\\v vMap v iSucc) 2 3 4)\n'
']' : '[[a b c d] [] [3 4 5]]',
'[\n'
'(tSet 3 <0 1 2> 0 1)\n'
'(tSet 4 <0 1 2 3> 4 1)\n'
'(tSet 5 <0 1 2 3 4> 4 5)\n'
']' : '[<1 1 2> <0 1 2 3> <0 1 2 3 5>]',
'[\n'
'(vFold [] 0 iAdd)\n'
'(vFold [1 2 3] 0 iAdd)\n'
'(vFold [1 2 3] 2 iMul)\n'
']' : '[0 6 12]',
'[\n'
'(vConcat [] [])\n'
'(vConcat [0 1 2] [3 4 5])\n'
'(vConcat [] [4 2 0])\n'
']' : '[[] [0 1 2 3 4 5] [4 2 0]]',
'[\n'
'(vExpand [] (\\e []))\n'
'(vExpand [0 1 2 3 4 5] (\\e iIsGT e 3 [e] []))\n'
'(vExpand [1 5 9] (\\e [e (iSucc e)]))\n'
']' : '[[] [4 5] [1 2 5 6 9 10]]',
'[\n'
'(vInsertStart [] 0)\n'
'(vInsertStart [1 2] 0)\n'
'(vInsertStart [2 4 0] 0)\n'
']' : '[[0] [0 1 2] [0 2 4 0]]',
'[\n'
'(vInsertEnd [] 0)\n'
'(vInsertEnd [1 2] 0)\n'
'(vInsertEnd [2 4 0] 0)\n'
']' : '[[0] [1 2 0] [2 4 0 0]]',
'[\n'
'(vLength [])\n'
'(vLength [1 2])\n'
'(vLength [2 4 0 3 1])\n'
']' : '[0 2 5]',
'[\n'
'(vFirstWhere [] (\\e true) 0)\n'
'(vFirstWhere [1 2 3] (\\e true) 0)\n'
'(vFirstWhere [1 2 3 4 5] (\\e iIsGT e 3) 0)\n'
']' : '[0 1 4]',
'[\n'
'(vTake [] 1)\n'
'(vTake [1 2 3] 6)\n'
'(vTake [1 2 3 4 5] 4)\n'
']' : '[[] [1 2 3] [1 2 3 4]]',
'[\n'
'(vSkip [] 1)\n'
'(vSkip [1 2 3] 6)\n'
'(vSkip [1 2 3 4 5] 2)\n'
']' : '[[] [] [3 4 5]]',
'[\n'
'(vGet [] 1 0)\n'
'(vGet [1 2 3] 0 0)\n'
'(vGet [1 2 3 4 5] 4 0)\n'
']' : '[0 1 5]',
'[\n'
'(vWhere [0 1 2] (\\e false))\n'
'(vWhere [1 2 3 4 5 6] (\\e iIsGT e 3))\n'
'(vWhere [0 1 0 3 5 0] iIsZero)\n'
']' : '[[] [4 5 6] [0 0 0]]',
'[\n'
'(vFoldMap [2 1 2 1] 0 \\st\\e <(iSucc st) (iAdd st e)>)\n'
'(vFoldMap [4 5 6 7] 1 \\st\\e <e (iAdd st e)>)\n'
'(vFoldMap [4 5 6 7] 1 \\st\\e <e (iMul st e)>)\n'
']' : '[[2 2 4 4] [5 9 11 13] [4 20 30 42]]',
'[\n'
'(vIndexify [])\n'
'(vIndexify [0 1 2])\n'
'(vIndexify [4 1 2 0])\n'
']' : '[[] [<0 0> <1 1> <2 2>] [<0 4> <1 1> <2 2> <3 0>]]',
'[\n'
'(vSet [0 1 2] 0 1)\n'
'(vSet [0 1 2 3] 4 1)\n'
'(vSet [0 1 2 3 4] 4 5)\n'
']' : '[[1 1 2] [0 1 2 3] [0 1 2 3 5]]',
'[\n'
'(vReverse [])\n'
'(vReverse [0 1 2])\n'
'(vReverse [6 9 6 9])\n'
']' : '[[] [2 1 0] [9 6 9 6]]',
'[\n'
'(vGenerate 0 1)\n'
'(vGenerate 1 2)\n'
'(vGenerate 3 3)\n'
']' : '[[] [2] [3 3 3]]',
'[\n'
'(vIsEmpty [])\n'
'(vIsEmpty [1])\n'
'(vIsEmpty [1 2 3])\n'
']' : '[true false false]',
'[\n'
'(vRemoveLast [])\n'
'(vRemoveLast [1])\n'
'(vRemoveLast [1 2 3])\n'
']' : '[[] [] [1 2]]',
'[\n'
'(vRemoveFirst [])\n'
'(vRemoveFirst [1])\n'
'(vRemoveFirst [1 2 3])\n'
']' : '[[] [] [2 3]]',
'[\n'
'(vSlice [] 0 1)\n'
'(vSlice [1 2 3] 0 2)\n'
'(vSlice [1 2 3 4 5] 1 4)\n'
']' : '[[] [1 2] [2 3 4]]',
'[\n'
'(vLast [] 6)\n'
'(vLast [1] 9)\n'
'(vLast [1 2 3] 4)\n'
']' : '[6 1 3]',
'[\n'
'(vFirst [] 6)\n'
'(vFirst [1] 9)\n'
'(vFirst [1 2 3] 4)\n'
']' : '[6 1 1]',
'[\n'
'(vIsEQ iIsEQ [] [])\n'
'(vIsEQ iIsEQ [1 2] [3 4])\n'
'(vIsEQ iIsEQ [1 2 3] [1 2])\n'
'(vIsEQ iIsEQ [1 2 3 4] [1 2 3 4])\n'
']' : '[true false false true]',
'[\n'
'(vTakeWhile [0 1 2] (\\e false))\n'
'(vTakeWhile [0 1 2] (\\e true))\n'
'(vTakeWhile [1 2 3 4 5 6] (\\e iIsLT e 4))\n'
'(vTakeWhile [0 0 0 3 5 0] iIsZero)\n'
']' : '[[] [0 1 2] [1 2 3] [0 0 0]]',
'[\n'
'(vSkipWhile [0 1 2] (\\e true))\n'
'(vSkipWhile [0 1 2] (\\e false))\n'
'(vSkipWhile [1 2 3 4 5 6] (\\e iIsLT e 4))\n'
'(vSkipWhile [0 0 0 3 5 0] (\\e iIsZero e))\n'
']' : '[[] [0 1 2] [4 5 6] [3 5 0]]',
'[\n'
'(vInsertAt [] 0 1)\n'
'(vInsertAt [] 1 1)\n'
'(vInsertAt [1] 0 2)\n'
'(vInsertAt [1] 1 2)\n'
'(vInsertAt [1 2 3 4] 2 9)\n'
']' : '[[1] [1] [2 1] [1 2] [1 2 9 3 4]]',
'[\n'
'(vReduce [] iAdd 0)\n'
'(vReduce [0 1 2 3] iAdd 0)\n'
'(vReduce [2 1 2 3] iMul 0)\n'
']' : '[0 6 12]',
'[\n'
'(vRemoveAt [] 0)\n'
'(vRemoveAt [] 1)\n'
'(vRemoveAt [1] 0)\n'
'(vRemoveAt [1] 1)\n'
'(vRemoveAt [1 2 3 4] 2)\n'
']' : '[[] [] [] [1] [1 2 4]]',
};
class MyTask implements Task {
final String code;
MyTask(this.code);
String execute () {
return (new TrashSolver(
new Parser().parse("test", "~\\\"stdlib.lf\"\n${code}")
..bind())
..solve()).expr.toString();
}
}
main() async {
var t = new DateTime.now();
var worker = new Worker(poolSize: 4, spawnLazily: false);
await Future.wait(tests.keys.map((code) async {
var f = worker.handle(new MyTask(code));
String res = await f;
if (res != tests[code]) {
print("Mismatch!");
print("code:\n$code");
print("expected:\n${tests[code]}");
}
}));
print("done");
print("took ${(new DateTime.now().millisecondsSinceEpoch - t.millisecondsSinceEpoch) / 1000}");
worker.close();
}
// henlo wherl
~\"util.lf"
~\owo "Gdmkn+"
~\wew "Vgdqk "
concat
(concat
(map owo succ)
" "
)
(map wew succ)
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/bin/packages" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/packages" />
<excludeFolder url="file://$MODULE_DIR$/test/packages" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
</component>
</module>
\ No newline at end of file
name: lambdafuck
description: A sample command-line application.
version: 0.0.1
#homepage: https://www.example.com
#author: pixel <email@example.com>
environment:
sdk: '>=1.20.1 <2.0.0'
#dependencies:
# path: ^1.4.1
dev_dependencies:
test: ^0.12.0
worker: "^0.5.0"
#Standard Library
###Util
```
null // the identity function \null null
return // is \x x
if b t f // is \b\t\f b t f
for start end iv l // equivalent to fold (vGenerateRange start end) iv l
while st lb l
// st = l(st) while lb(st) is true
until st lb l
// st = l(st) until lb(st) is true
// equivalent to while (l st) (\b bNot (lb b)) l
```
###Tuple
```
tPair a b // makes a pair with a and b
(t) tFirst // gets the first value of a pair
tSetFirst t v // sets the first value of a pair to v
(t) tSecond // gets the second value of a pair
tSetSecond t v // sets the second value of a pair to v
tVararg i f ... // reads a variable number of arguments to a vector and return f(v)
tTuple i ... // makes a tuple with i length
(t) (tGet i p) // gets the value at p from a tuple with i length
tSet t i n v // sets t[n] of tuple length i to v
tVector i t // turns a tuple into a vector
```
###Bool
```
true // is \t\f t
false // is \t\f f
bNot x // returns !x
bOr x y // returns x || y
bAnd x y // returns x && y
bXor x y // returns x ^ y
```
###Int
```
iSucc x // returns x + 1
iPred x // returns x - 1
iAdd x y // returns x + y
iSub x y // returns x - y
iMul x y // returns x * y
iDiv x y // returns x / y
iExp x y // returns exp(x, y)
iIsZero x // returns x == 0
iIsGT x y // return x > y
iIsLT x y // return x < y
iIsGE x y // return x >= y
iIsLE x y // return x <= y
iIsEQ x y // return x == y
iSigned x // converts x to signed
```
###Signed Int
```
sSucc x // returns x + 1
sPred x // returns x - 1
sNeg x // returns -x
sAdd x y // returns x + y
sSub x y // returns x - y
sMul x y // returns x * y
sDiv x y // returns x / y
sIsZero x // returns x == 0
sIsGT x y // return x > y
sIsLT x y // return x < y
sIsGE x y // return x >= y
sIsLE x y // return x <= y
sIsEQ x y // return x == y
sIsNEQ x y // return x != y
sNormalize x // normalizes x so that at least one side is zero
sUnsigned x // converts x to unsigned number
```
###Vector
```
vGet v i d // returns v[i] or d if out of bounds (zero indexed)
vSet v i e // returns v where v[i] = e
vLast v d // returns the last value in v or d if empty
vFirst v d // returns the first value in v or d if empty
vLength v // returns v.length
vReverse v // returns the reverse of v
vTake v i // returns the first i values of the vector
vTakeWhile v l // returns the values of v until l(v[i]) is false
vSkip v i // returns the vector but skips the first i elements
vSkipWhile v l // returns the values of v starting when l(v[i]) is truevFirstWhere v l d // returns the first element where l(e) returns true, d if none are found
vMap v l
// returns v.map(l) where l is a llama that takes an element and returns the replacement
// so that out[n] = l(v[n])
vFoldMap v iv lf
// same as map but keeps a state so that out[n], st = l(st, v[n])
vWhere v l
// returns v.where(l) where l is a llama that takes an element and returns a boolean
// the output is an array where l returned true
vReduce v l d
// reduces v to a single value by combining them with l(e1, e2) or d if v is empty
vFold v iv l
// reduces a vector to a single value where iv is the initial value
// l is a lambda that takes the previous value (iv if first element) and the current element
// and returns the next value to pass to the callback or return value if its the last element
vExpand v l
// expand function like dart's Iterable.expand
vIndexify v // returns an array where out[i] = mkTuple(i, out[i])
vGenerate j e // generates a Vector with j elements and filling it with e
vGenerateRange i j // generates a Vector of integers starting at i and ending before j
vIsEmpty v // returns true if v is empty, else returns false
vRemoveLast v // removes the last element
vRemoveFirst v // removes the first element
vRemoveAt v i // removes element at i
vRemoveRange v start end // removes range of elements
vInsertEnd v e // inserts e at the end of v
vInsertStart v e // inserts e at the start of v
vInsertAt v i e // inserts e into v at i
vConcat va vb // appends vb to va
vSlice v start end // returns a slice of v from start to before end
vEquals cmp a b // returns true if both vectors have the same contents using cmp
```
~\ded (\code\input
~\jmp (getjmp code)
~\jmpFwd (jmp (tGet 3 1))
~\jmpBack (jmp (tGet 3 2))
~\indexMap (\v\i
(vFirstWhere v (\e iIsEq (e tFirst) i) 0) tSecond
)
~\codeLength (vLength code)
~\pc (tGet 5 0)
~\setPc (\st\v tSet st 5 0 v)
~\ptr (tGet 5 1)
~\setPtr (\st\v tSet st 5 1 v)
~\mem (tGet 5 2)
~\setMem (\st\v tSet st 5 2 v)
~\out (tGet 5 3)
~\setOut (\st\v tSet st 5 3 v)
~\inputIndex (tGet 5 4)
~\setInputIndex (\st\v tSet st 5 4 v)
~\byteSucc (\n
(iIsEQ n 255) 0 (iSucc n)