add inner (of lists) type, add floor, ceil, and roundd standard functions, and a ton of examples
This commit is contained in:
parent
5bcab07681
commit
efbe5a9f97
20 changed files with 330 additions and 46 deletions
43
bad.ang
43
bad.ang
|
|
@ -1,5 +1,40 @@
|
||||||
import "lib/list.ang"
|
import "lib/math.ang"
|
||||||
|
|
||||||
write(str(map([1, 2, 3], func(n: number) number {
|
primes := [2]
|
||||||
return n*n
|
|
||||||
})))
|
func is_prime(x: number) boolean {
|
||||||
|
i := 0
|
||||||
|
while i < primes.length() && primes.at(i)*primes.at(i) < x {
|
||||||
|
if mod(x, primes.at(i)) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
i = i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
n := 1
|
||||||
|
max := 100000
|
||||||
|
|
||||||
|
while n < max {
|
||||||
|
n = n + 2
|
||||||
|
|
||||||
|
if is_prime(n) {
|
||||||
|
primes.append(n)
|
||||||
|
|
||||||
|
# Update counter
|
||||||
|
print(char(0x0D))
|
||||||
|
print(str(n))
|
||||||
|
print("/")
|
||||||
|
print(str(max))
|
||||||
|
print(char(0x09))
|
||||||
|
print(str(roundd(n/max*100, 2)))
|
||||||
|
print("%")
|
||||||
|
print(char(0x09))
|
||||||
|
print(str(primes.length()))
|
||||||
|
print(" primes")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write(str(primes))
|
||||||
|
|
|
||||||
15
chars.ang
Normal file
15
chars.ang
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
MAX_WIDTH := 16
|
||||||
|
|
||||||
|
print(" ")
|
||||||
|
w := 1
|
||||||
|
n := 0x21
|
||||||
|
while n < 0xA0 {
|
||||||
|
print(char(n))
|
||||||
|
n = n + 1
|
||||||
|
w = w + 1
|
||||||
|
if w >= MAX_WIDTH {
|
||||||
|
write("")
|
||||||
|
w = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
24
codegen.ang
Normal file
24
codegen.ang
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
passphrase := "Hello world!".split("")
|
||||||
|
start := [0, 0, 0]
|
||||||
|
modulus := 10
|
||||||
|
base := byte("!")
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
n := 0
|
||||||
|
while n < passphrase.length() {
|
||||||
|
b := byte(passphrase.at(n))
|
||||||
|
|
||||||
|
v = start.at(i) + b - base
|
||||||
|
while v >= modulus {
|
||||||
|
v = v - modulus
|
||||||
|
}
|
||||||
|
|
||||||
|
start.put(i, v)
|
||||||
|
|
||||||
|
if i >= 3 {
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
n = n + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -404,12 +404,22 @@ func (c *Compiler) compile(tree Node) error {
|
||||||
return c.error(fmt.Sprintf("argument #%d does not have expected type signature: got %s, requires %s", i, sig, f.In[i]), arg)
|
return c.error(fmt.Sprintf("argument #%d does not have expected type signature: got %s, requires %s", i, sig, f.In[i]), arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.isTreeConstant(arg) {
|
||||||
|
v, err := c.compute(arg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.add(InstructionConstant)
|
||||||
|
c.addConstant(v)
|
||||||
|
} else {
|
||||||
err = c.compile(arg)
|
err = c.compile(arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
err = c.compile(n.source)
|
err = c.compile(n.source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -716,6 +726,18 @@ func (c *Compiler) deduceSignature(tree Node) (TypeSignature, error) {
|
||||||
return nil, c.error(fmt.Sprintf("bad argument count (expected %v, got %v)", len(f.In), len(n.args)), n)
|
return nil, c.error(fmt.Sprintf("bad argument count (expected %v, got %v)", len(f.In), len(n.args)), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var innerType TypeSignature
|
||||||
|
if n.source.Type() == AccessNodeType {
|
||||||
|
member, err := c.deduceSignature(n.source.(*AccessNode).source)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if member.Type() == TypeList {
|
||||||
|
innerType = member.(*ListSignature).Contents
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// type check arguments
|
// type check arguments
|
||||||
for i, arg := range n.args {
|
for i, arg := range n.args {
|
||||||
sig, err := c.deduceSignature(arg)
|
sig, err := c.deduceSignature(arg)
|
||||||
|
|
@ -723,11 +745,28 @@ func (c *Compiler) deduceSignature(tree Node) (TypeSignature, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sig.Matches(f.In[i]) {
|
t := f.In[i]
|
||||||
|
if t.Type() == TypeInner {
|
||||||
|
if innerType == nil {
|
||||||
|
return nil, c.error(fmt.Sprintf("function source (%s) has no inner type", sig), n.source)
|
||||||
|
}
|
||||||
|
|
||||||
|
t = innerType
|
||||||
|
}
|
||||||
|
|
||||||
|
if !sig.Matches(t) {
|
||||||
return nil, c.error(fmt.Sprintf("argument #%d has wrong type signature. requires %s, got %s", i, f.In[i], sig), arg)
|
return nil, c.error(fmt.Sprintf("argument #%d has wrong type signature. requires %s, got %s", i, f.In[i], sig), arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.Out.Type() == TypeInner {
|
||||||
|
if innerType == nil {
|
||||||
|
return nil, c.error(fmt.Sprintf("function source (%s) has no inner type", sig), n.source)
|
||||||
|
}
|
||||||
|
|
||||||
|
return innerType, nil
|
||||||
|
}
|
||||||
|
|
||||||
return f.Out, nil
|
return f.Out, nil
|
||||||
|
|
||||||
case FunctionNodeType:
|
case FunctionNodeType:
|
||||||
|
|
@ -954,7 +993,14 @@ func (c *Compiler) isTreeConstant(tree Node) bool {
|
||||||
return true
|
return true
|
||||||
case BinaryNodeType:
|
case BinaryNodeType:
|
||||||
return c.isTreeConstant(tree.(*BinaryNode).Left) && c.isTreeConstant(tree.(*BinaryNode).Right)
|
return c.isTreeConstant(tree.(*BinaryNode).Left) && c.isTreeConstant(tree.(*BinaryNode).Right)
|
||||||
case BlockNodeType, ConditionalNodeType, LoopNodeType, AssignNodeType, CallNodeType, FunctionNodeType,
|
case CallNodeType:
|
||||||
|
for _, arg := range tree.(*CallNode).args {
|
||||||
|
if !c.isTreeConstant(arg) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c.isTreeConstant(tree.(*CallNode).source)
|
||||||
|
case BlockNodeType, ConditionalNodeType, LoopNodeType, AssignNodeType, FunctionNodeType,
|
||||||
ReturnNodeType, AccessNodeType, BreakpointNodeType, ReferenceNodeType:
|
ReturnNodeType, AccessNodeType, BreakpointNodeType, ReferenceNodeType:
|
||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
|
|
@ -1009,6 +1055,31 @@ func (c *Compiler) compute(tree Node) (Value, error) {
|
||||||
-v.(*NumberValue).Number,
|
-v.(*NumberValue).Number,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
|
case *CallNode:
|
||||||
|
source, err := c.compute(n.source)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
f, ok := source.(*BuiltinFunctionValue)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !f.Constant {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]Value, len(f.Signature.In))
|
||||||
|
for i, arg := range n.args {
|
||||||
|
args[i], err = c.compute(arg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.F(nil, nil, args)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unexpected node %s, %T", tree.String(), tree))
|
panic(fmt.Sprintf("unexpected node %s, %T", tree.String(), tree))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ const (
|
||||||
TypeFunction
|
TypeFunction
|
||||||
TypeAny
|
TypeAny
|
||||||
TypeComposite
|
TypeComposite
|
||||||
|
TypeInner
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t Type) String() string {
|
func (t Type) String() string {
|
||||||
|
|
@ -39,6 +40,8 @@ func (t Type) String() string {
|
||||||
return "any"
|
return "any"
|
||||||
case TypeComposite:
|
case TypeComposite:
|
||||||
return "composite"
|
return "composite"
|
||||||
|
case TypeInner:
|
||||||
|
return "inner"
|
||||||
}
|
}
|
||||||
|
|
||||||
panic(fmt.Sprintf("unsupported string conversion for type %v", int(t)))
|
panic(fmt.Sprintf("unsupported string conversion for type %v", int(t)))
|
||||||
|
|
@ -330,3 +333,17 @@ func (s *CompositeSignature) Matches(other TypeSignature) bool {
|
||||||
func (s *CompositeSignature) String() string {
|
func (s *CompositeSignature) String() string {
|
||||||
return fmt.Sprintf("%s|%s", s.A, s.B)
|
return fmt.Sprintf("%s|%s", s.A, s.B)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InnerSignature struct{}
|
||||||
|
|
||||||
|
func (*InnerSignature) Type() Type {
|
||||||
|
return TypeInner
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*InnerSignature) Matches(_ TypeSignature) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*InnerSignature) String() string {
|
||||||
|
return "inner"
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -434,7 +434,7 @@ var ListPrototype = map[string]*BuiltinFunctionValue{
|
||||||
[]TypeSignature{
|
[]TypeSignature{
|
||||||
&NumberSignature{},
|
&NumberSignature{},
|
||||||
},
|
},
|
||||||
&AnySignature{},
|
&InnerSignature{},
|
||||||
},
|
},
|
||||||
func(_ *VM, this Value, p []Value) (Value, error) {
|
func(_ *VM, this Value, p []Value) (Value, error) {
|
||||||
items := this.(*ListValue).Items
|
items := this.(*ListValue).Items
|
||||||
|
|
|
||||||
42
core/vm.go
42
core/vm.go
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -479,6 +480,45 @@ var DefaultGlobals = map[string]Value{
|
||||||
nil,
|
nil,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
"floor": &BuiltinFunctionValue{
|
||||||
|
"floor",
|
||||||
|
&FunctionSignature{
|
||||||
|
[]TypeSignature{&NumberSignature{}},
|
||||||
|
&NumberSignature{},
|
||||||
|
},
|
||||||
|
func(vm *VM, this Value, args []Value) (Value, error) {
|
||||||
|
return &NumberValue{math.Floor(args[0].(*NumberValue).Number)}, nil
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
"ceil": &BuiltinFunctionValue{
|
||||||
|
"ceil",
|
||||||
|
&FunctionSignature{
|
||||||
|
[]TypeSignature{&NumberSignature{}},
|
||||||
|
&NumberSignature{},
|
||||||
|
},
|
||||||
|
func(vm *VM, this Value, args []Value) (Value, error) {
|
||||||
|
return &NumberValue{math.Ceil(args[0].(*NumberValue).Number)}, nil
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
"roundd": &BuiltinFunctionValue{
|
||||||
|
"roundd",
|
||||||
|
&FunctionSignature{
|
||||||
|
[]TypeSignature{&NumberSignature{}, &NumberSignature{}},
|
||||||
|
&NumberSignature{},
|
||||||
|
},
|
||||||
|
func(vm *VM, this Value, args []Value) (Value, error) {
|
||||||
|
x := args[0].(*NumberValue).Number
|
||||||
|
decimals := args[1].(*NumberValue).Number
|
||||||
|
multiplier := math.Pow(10, decimals)
|
||||||
|
return &NumberValue{math.Round(x*multiplier) / multiplier}, nil
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVM(chunk *Chunk, stackSize Pos, callstackSize Pos) *VM {
|
func NewVM(chunk *Chunk, stackSize Pos, callstackSize Pos) *VM {
|
||||||
|
|
@ -813,9 +853,7 @@ func (vm *VM) Call(v Value, args []Value) (Value, error) {
|
||||||
for vm.chunk.Bytecode[vm.ip] != InstructionReturn && vm.Next() {
|
for vm.chunk.Bytecode[vm.ip] != InstructionReturn && vm.Next() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if vm.HasNext() {
|
|
||||||
vm.Next()
|
vm.Next()
|
||||||
}
|
|
||||||
|
|
||||||
return vm.stack.Pop(), nil
|
return vm.stack.Pop(), nil
|
||||||
|
|
||||||
|
|
|
||||||
2
emoji.ang
Normal file
2
emoji.ang
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
write(char(0x12) + char(0x85) + char(0x07))
|
||||||
0
examples/brainfuck.ang
Normal file
0
examples/brainfuck.ang
Normal file
|
|
@ -1,15 +1,14 @@
|
||||||
|
# This program computes the fibonacci numbers using recursion (O(2^n))
|
||||||
# fibonacci sequence
|
# It is very slow
|
||||||
func fib(n) {
|
func fib(x: number) number {
|
||||||
if n <= 1 {
|
if x <= 1 {
|
||||||
return n
|
return x
|
||||||
}
|
}
|
||||||
|
return fib(x - 1) + fib(x - 2)
|
||||||
return fib(n - 1) + fib(n - 2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n := 0
|
n := 0
|
||||||
while n < 10 {
|
while n < 100 {
|
||||||
write(fib(n))
|
write(str(fib(n)))
|
||||||
n = n + 1
|
n = n + 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
examples/solving.ang
Normal file
13
examples/solving.ang
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import "../lib/math.ang"
|
||||||
|
|
||||||
|
a := 120
|
||||||
|
b := 10
|
||||||
|
|
||||||
|
# find log_b(a)
|
||||||
|
func f(x: number)number {
|
||||||
|
return pow(b, x) - a
|
||||||
|
}
|
||||||
|
|
||||||
|
log_b := newtons(f)
|
||||||
|
write(str(log_b))
|
||||||
|
write("inverse: "+str(pow(b, log_b))+" = "+str(a))
|
||||||
4
fails.ang
Normal file
4
fails.ang
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
import "lib/honning.ang"
|
||||||
|
|
||||||
|
write(_bell+_italic+"Hello "+_underline+"world "+_strike+"micheal"+_reset)
|
||||||
|
|
||||||
15
imp.ang
Normal file
15
imp.ang
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
func is_cool(x: number|string) boolean {
|
||||||
|
if x == "cool" {
|
||||||
|
return true
|
||||||
|
} else if x == 69 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
write(str(is_cool("not cool")))
|
||||||
|
write(str(is_cool("cool")))
|
||||||
|
write(str(is_cool(0)))
|
||||||
|
write(str(is_cool(69)))
|
||||||
15
lib/honning.ang
Normal file
15
lib/honning.ang
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
_bell := char(0x07)
|
||||||
|
|
||||||
|
ESC := char(0x1B)
|
||||||
|
CSI := ESC + "["
|
||||||
|
|
||||||
|
_reset := CSI + "0m"
|
||||||
|
_bold := CSI + "1m"
|
||||||
|
_faint := CSI + "2m"
|
||||||
|
_italic := CSI + "3m"
|
||||||
|
_underline := CSI + "4m"
|
||||||
|
_slow_blink := CSI + "5m"
|
||||||
|
_rapid_blink := CSI + "6m"
|
||||||
|
_strike := CSI + "9m"
|
||||||
|
_primary_font := CSI + "10m"
|
||||||
64
lib/math.ang
64
lib/math.ang
|
|
@ -17,6 +17,24 @@ func abs(x: number) number {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DERIVE_DX := 0.00000001
|
||||||
|
func derive(f: func(number)number, x: number) number {
|
||||||
|
return (f(x + DERIVE_DX) - f(x))/DERIVE_DX
|
||||||
|
}
|
||||||
|
|
||||||
|
NEWTONS_ACC := 0.000000000001
|
||||||
|
func newtons(f: func(number)number) number {
|
||||||
|
pg := 0
|
||||||
|
g := 1
|
||||||
|
|
||||||
|
while abs(g - pg) > NEWTONS_ACC {
|
||||||
|
pg = g
|
||||||
|
g = pg - f(pg) / derive(f, pg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
|
||||||
MAX_SQRT_DX := 0.0000001
|
MAX_SQRT_DX := 0.0000001
|
||||||
|
|
||||||
# sqrt(x)
|
# sqrt(x)
|
||||||
|
|
@ -42,18 +60,14 @@ func sqrt(x: number) number {
|
||||||
# Return the whole number part of the number. if x is a whole number,
|
# Return the whole number part of the number. if x is a whole number,
|
||||||
# the returned value is x. If x is not a whole number, the closest
|
# the returned value is x. If x is not a whole number, the closest
|
||||||
# whole number which is less than or equal to x is returned.
|
# whole number which is less than or equal to x is returned.
|
||||||
func floor(x: number) number {
|
|
||||||
# todo
|
|
||||||
}
|
|
||||||
|
|
||||||
# ceil(x)
|
# ceil(x)
|
||||||
# x: number
|
# x: number
|
||||||
# Return the whole number part of the number. if x is a whole number,
|
# Return the whole number part of the number. if x is a whole number,
|
||||||
# the returned value is x. If x is not a whole number, the closest
|
# the returned value is x. If x is not a whole number, the closest
|
||||||
# whole number which is greater than or equal to x is returned.
|
# whole number which is greater than or equal to x is returned.
|
||||||
func ceil(x: number) number {
|
|
||||||
# todo
|
|
||||||
}
|
|
||||||
|
|
||||||
# round(x)
|
# round(x)
|
||||||
# x: number
|
# x: number
|
||||||
|
|
@ -72,7 +86,7 @@ func round(x: number) number {
|
||||||
# x: number; any number
|
# x: number; any number
|
||||||
# n: number; the number to divide by
|
# n: number; the number to divide by
|
||||||
# Return the rest from a division of x by n.
|
# Return the rest from a division of x by n.
|
||||||
func mod(x: number, n: number) {
|
func mod(x: number, n: number) number {
|
||||||
if x == 0 {
|
if x == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +150,23 @@ func exp(x: number) number {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ln(x)
|
||||||
|
# x: number; any number
|
||||||
|
# Get the approximate value of the natural logarithm
|
||||||
|
# This function uses newton's method to approximate.
|
||||||
|
LN_ACC := 0.0000000001
|
||||||
|
func ln(x: number) number {
|
||||||
|
pg := 0
|
||||||
|
g := 1
|
||||||
|
|
||||||
|
while abs(pg - g) > LN_ACC {
|
||||||
|
pg = g
|
||||||
|
g = pg + x / exp(pg) - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
|
||||||
# pow(x, p)
|
# pow(x, p)
|
||||||
# x: number; any number. The base
|
# x: number; any number. The base
|
||||||
# p: number; the value of the exponent
|
# p: number; the value of the exponent
|
||||||
|
|
@ -144,18 +175,21 @@ func pow(x: number, p: number) number {
|
||||||
return exp(p*ln(x))
|
return exp(p*ln(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
# ln(x)
|
# log(x, b)
|
||||||
# x: number; any number
|
# x: number; any number greater than 0
|
||||||
# Get the approximate value of the natural logarithm
|
# b: number; any number as the base
|
||||||
# This function uses newton's method to approximate.
|
# Calculate the approximate value of the logarithm
|
||||||
LN_ACC := 0.000000001
|
# of a with b as base.
|
||||||
func ln(x: number) number {
|
LOG_ACC := 0.0000001
|
||||||
|
func log(a: number, b: number) number {
|
||||||
|
ln_b := ln(b)
|
||||||
|
|
||||||
pg := 0
|
pg := 0
|
||||||
g := 1
|
g := 1
|
||||||
|
|
||||||
while abs(pg - g) > LN_ACC {
|
while abs(g - pg) > LOG_ACC {
|
||||||
pg = g
|
pg = g
|
||||||
g = pg + x / exp(pg) - 1
|
g = pg - 1/ln_b - a/(ln_b*pow(b, pg))
|
||||||
}
|
}
|
||||||
|
|
||||||
return g
|
return g
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ done
|
||||||
|
|
||||||
|
|
||||||
if [ 0 -ne "$(wc -w <<< "${errors[@]}")" ]; then
|
if [ 0 -ne "$(wc -w <<< "${errors[@]}")" ]; then
|
||||||
echo "== Errors occured while executing =="
|
echo "=x= Errors occured while executing =x="
|
||||||
echo "erroring files: $(printf '%s ' "${errors[@]}")"
|
echo "erroring files: $(printf '%s ' "${errors[@]}")"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo '== Successfully ran all tests =='
|
echo '=+= Successfully ran all tests =+='
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@ assertEq(1, 1)
|
||||||
assertEq(0, 0)
|
assertEq(0, 0)
|
||||||
assertEq("", "")
|
assertEq("", "")
|
||||||
|
|
||||||
assertEq([], [])
|
assertEq([]number, []number)
|
||||||
assertEq([3, 1, 4, 1], [3, 1, 4, 1])
|
assertEq([3, 1, 4, 1], [3, 1, 4, 1])
|
||||||
assertEq([true, 1024, nil, "Hello world!"], [true, 1024, nil, "Hello world!"])
|
|
||||||
|
|
||||||
# Inequality
|
# Inequality
|
||||||
assertNotEq(2, 3)
|
assertNotEq(2, 3)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
list := []
|
list := []number
|
||||||
|
|
||||||
x := 1
|
x := 1
|
||||||
while x <= 1000 {
|
while x <= 1000 {
|
||||||
|
|
@ -14,7 +14,7 @@ func sum(a: number, b: number) number {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
list = []
|
list = []number
|
||||||
x = 1
|
x = 1
|
||||||
while x <= 100 {
|
while x <= 100 {
|
||||||
list.append(2*x - 1)
|
list.append(2*x - 1)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
list := []
|
list := []number
|
||||||
|
|
||||||
list.append(1)
|
list.append(1)
|
||||||
list.append(2)
|
list.append(2)
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,12 @@ a := 2
|
||||||
{
|
{
|
||||||
a := 3
|
a := 3
|
||||||
assertEq(a, 3)
|
assertEq(a, 3)
|
||||||
|
breakpoint
|
||||||
|
|
||||||
a = 4
|
a = 4
|
||||||
assertEq(a, 4)
|
assertEq(a, 4)
|
||||||
|
breakpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEq(a, 2)
|
assertEq(a, 2)
|
||||||
|
breakpoint
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue