static type analysis, formatted compiler errors, hex support, composite types, updated cli, more global builtins, fix list form, fix value refs

This commit is contained in:
Neemek 2025-03-18 20:22:46 +01:00
parent 84cc845748
commit 954308b29f
Signed by: neemek
GPG key ID: 28360A8951CD0E9B
18 changed files with 1352 additions and 285 deletions

14
lib/assert.ang Normal file
View file

@ -0,0 +1,14 @@
func assertEqual(a: any, b: any) {
if a != b {
write(format("assertion error: % should (but doesn't) equal %", [a, b]))
exit(1)
}
}
func assertNotEqual(a: any, b: any) {
if a == b {
write(format("assertion error: % shouldn't (but does) equal %", [a, b]))
exit(1)
}
}

206
lib/math.ang Normal file
View file

@ -0,0 +1,206 @@
PI := 3.14159265358979323
E := 2.718281828459045235360287471352
# abs(x)
# x: number
# Get the absolute value of a number. If x is negative, the returned
# value is positive and equal to `-x`. If x is positive or zero, the
# returned value is x.
func abs(x: number) number {
# if the number is negative
if x < 0 {
# negate it so it's positive
return -x
}
return x
}
MAX_SQRT_DX := 0.0000001
# sqrt(x)
# x: number
# Calculate the approximate square root using newton's method until
# the accuracy has increased by less than the variable `MAX_SQRT_DX`.
func sqrt(x: number) number {
ng := x
g := 1
while abs(g - ng) > MAX_SQRT_DX {
g = ng
# create new guess
ng = (g + x / g) / 2
}
return g
}
# floor(x)
# x: 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
# whole number which is less than or equal to x is returned.
func floor(x: number) number {
# todo
}
# ceil(x)
# x: 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
# whole number which is greater than or equal to x is returned.
func ceil(x: number) number {
# todo
}
# round(x)
# x: number
# Return the closest whole number to the value x.
func round(x: number) number {
f := floor(x)
if x - f > 0.5 {
return f + 1
}
return f
}
# mod(x, n)
# x: number; any number
# n: number; the number to divide by
# Return the rest from a division of x by n.
func mod(x: number, n: number) {
if x == 0 {
return 0
}
if x < 0 {
while x + n <= 0 {
x = x + n
}
} else {
while x - n >= 0 {
x = x - n
}
}
return x
}
# sm_exp(x)
# x: number; any number between 0 and 1
# Get an approximate value of e raised to the power of x.
# This value is only reasonable if 0<x<1.
# It is approximated using the taylor series of e**x.
SM_EXP_ACC := 0.00000000001
func sm_exp(x: number) number {
p_tot := 0
tot := 1
n := 1
x_pow := x
f := 1
while abs(tot - p_tot) > SM_EXP_ACC {
p_tot = tot
t := x_pow / f
tot = tot + t
f = f * (n+1)
x_pow = x_pow * x
n = n + 1
}
return tot
}
# exp(x)
# x: number; any number
# Get an approximate value of e raised to the power of x.
func exp(x: number) number {
n := abs(x)
tot := 1
while n >= 1 {
tot = tot * E
n = n - 1
}
if n > 0 {
tot = tot * sm_exp(n)
}
if x < 0 {
return 1/tot
} else {
return tot
}
}
# pow(x, p)
# x: number; any number. The base
# p: number; the value of the exponent
# Raise any number to any power (x^p)
func pow(x: number, p: number) number {
return exp(p*ln(x))
}
# 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.000000001
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
}
# sin(x)
# x: number; an angle in radians
# Get the sine of an angle (in radians). https://en.wikipedia.org/wiki/Sine_and_cosine
# TODO: use hashmap with precomputed values and linear interpolation
func sin(x: number) number {
f := 1
x = mod(x, 2*PI)
if x > PI {
x = PI - x
f = -1
}
# compute sine with a taylor series mock function of sine (valid between -pi and +pi)
tot := x
l := 1
i := 1
s := -1
while i <= 19 {
i = i + 2
l = s * l * x / i / (i-1)
tot = tot + l
s = -s
}
return tot*f
}
# cos(x)
# x: number; an angle in radians
# Get the cosine of an angle (in radians). https://en.wikipedia.org/wiki/Sine_and_cosine
func cos(x: number) number {
# todo
}
# tan(x)
# x: number; an angle in radians
# Get the tangent of an angle. https://en.wikipedia.org/wiki/Tangent
func tan(x: number) number {
# todo
}