This commit is contained in:
ProgramSnail 2023-03-31 12:10:12 +03:00
parent 582ad5668e
commit 0d62ae0814
29 changed files with 99479 additions and 1166 deletions

29
tests/arrays.lang Normal file
View file

@ -0,0 +1,29 @@
decl test_arrays : Unit -> Unit
def test_arrays = {
var arr1 = [1, 2, 3]
const arr2 = [] // empty array ??
var arr3 = [] : Int.5 // TODO: decide ??
const arr4= ['a'..'z']
const n = 100;
var @arr5 = @[] : @Int.n // unique pointer (??)
var @@arr6 = @@[] : @@Int.n // shared pointer (??)
var @@arr6_pointer = @@arr6
const elem1 = arr1.1
var elem2 = arr1.1
const *ref1 = *arr1.1 // reference <-> unmanaged pointer (??)
var *ref2 = *arr1.1
; *arr1.1 = 123
; ref1 = arr1.2 // set value
; *ref1 = *ref2 // set reference
// ?? references, that can't change ??
// ?? array access, array mutable access, array get reference to elem ??
// ?? arrays as basic type ??
// ?? custom allocators ??
}
// ????????????????????

69
tests/classes.lang Normal file
View file

@ -0,0 +1,69 @@
// ?? value - parametric classes ??
// struct fields/etc. accessible from everywere
// class fields/etc. accessible only from namespace of class or class instance (from "methods")
// points at the beginning of constructor name - amount of needed constructor prefixes ?
// ?? how to make class compositons ??
struct Fruit =
| Apple
| Orange
| Banana
struct Optional 'A =
| Some & 'A
| None
struct (Result : #Move) 'A 'B =
| & 'A
| Error & 'B
// struct (Complex : #Value) =
// & Float(0.0)
// & Float(0.0)
//
// struct Task =
// & name("Task") : String
// & duration(0.0) : Float
class Employee =
& name : String
& role :
( | Director
& importance : Float
& share : Float
| Manager
& productivity :
( Productivity
| .Low
| .Average
| .High
& duration : Float
& sleep_on_work :
(SleepOnWork
| ..Yes
| ..No
))
& salary : Int
| Programmer
& skills : Float
& current_task : Optional Task
& salary : Int)
class Bag =
&
( | Apple
| Orange
| Banana)
& bag_type :
( | Small
| Medium
& weight_kg : Int
& weight_g : Int
& weight_g : Int
| Big)
& other_things : Array Something

View file

@ -0,0 +1,43 @@
namespace Employee {
decl gen_employee : Unit -> Employee
def gen_employee = {
; a = b + c
return
$Employee
& name = "John"
& role =
($Manager
& name = "John"
& productivity =
($Productivity.High
& duration = 10.3
& sleep_on_work = ($Productivity.SleepOnWork.No))
& salary = 123)
}
}
/*
class Employee =
& name : String
& role :
( | Director
& importance : Float
& share : Float
| Manager
& productivity :
( Productivity
| .Low
| .Average
| .High
& duration : Float
& sleep_on_work :
(SleepOnWork
| ..Yes
| ..No
))
& salary : Int
| Programmer
& skills : Float
& current_task : Optional Task
& salary : Int)
*/

44
tests/flow_control.lang Normal file
View file

@ -0,0 +1,44 @@
decl flow_control_test : Unit -> Unit
def flow_control_test = {
// if && || a < b
// || a == b
// && b < c
// && c > 10
if ((a < b) || (a == b)) && (b < c)
then IO.print x
elif x < 0
then {
; ++x
; IO.print y
} else {
return {}
}
while (a > 0) && (!array.is_empty)
do {
; --a
; array.pop
}
while x < 10 do
x += x + 3
for i in 0..y do {
; IO.print i
}
for & i & j
in (& 0..y & 0..k)
do { // TODO: decide ??? does it work (like auto zip) ???
; IO.print 1
; IO.print 2
; IO.print 128
}
loop {
; ++y
if y > 100 then
break
}
}

70
tests/functions.lang Normal file
View file

@ -0,0 +1,70 @@
// "decl" is not required, but useful in module interface
decl sum ('A : #Add) : 'A -> 'A -> 'A
def sum : a b = a + b
decl fib : Int -> Int
def fib : n =
match n with
| 0 | 1 -> 1
| _ -> fib (n - 1) + fib n
decl fact : Int -> Int
def fact : n =
match n with
| 0 -> 1
| n -> n * fact (n - 1)
decl find_prefix_hashes ('H : (#AccHash Char)) : String -> Array 'H
def find_prefix_hashes ('H : (#AccHash Char)) : str = {
var hashes = (Array 'H).new (str.size + 1)
; hashes.0 = 'H.of str.0
for i in 1..hashes.size do {
; hashes.i = hashes.(i - 1).clone
; hashes.i.append str.i
}
return hashes
}
// ?? other default constructor symbol (instead of placeholder _), etc. ??
// seporate first and last iteration of loop ?
// previous and next iterations ?
decl find_substring : String -> String -> Array Index
def find_substring : str substr = {
alias Hash = AccHash Char
var result = (Array Index).empty
const str_hashes = find_prefix_hashes Hash str
const substr_hash = Hash.of substr
for i in 0..(str_hashes.size - substr.size) do {
const part_hash = Hash.diff str_hashes.(i + substr.size) str_hashes.i
if part_hash == substr_hash then {
; result.push i
}
}
return result
}
decl is_empty : Unit -> Bool
def is_empty =
return 0
decl do_something : Unit -> Unit
def do_something =
IO.print "Hello World!"
decl mul : Int -> Int -> Int
def mul : x y = x * y
decl mul_10 : Int -> Int
def mul_10 = mul 10 // or argument can be used
// ?? is partial application feature needed ??

18
tests/import.lang Normal file
View file

@ -0,0 +1,18 @@
import "module"
import "module" : func
import "module" :
func1
func2
func3
func4
func5
use ModuleNamespace = import "module"
use PartOfModuleNamespace =
import "module" :
func1
func2
func3
// ?? use ":" once again ??

15
tests/lambdas.lang Normal file
View file

@ -0,0 +1,15 @@
decl test_lambdas : Unit -> Unit
def test_lambdas = {
const lambda1 = \x -> x * x
// const lambda2 = \(x : #Hash) -> x.hash // ??
const lambda3 = \x y -> x + y
// TODO: type LambdaType = Int -> Int // ?? type keyword ??
// const typed_lambda = \x -> x + 1
const lambda4 = \x -> {
; IO.print x
const y = x + x
return y
}
}

15
tests/match.lang Normal file
View file

@ -0,0 +1,15 @@
def fruit_cost : fruit = {
return (match fruit with
| $Banana -> 11
| $Apple | $Orange -> 7)
}
def amount_to_string : x is_zero_separated = {
const ans = match x with
| 0 ? is_zero_separated -> "Zero"
| 0 | 1 | 2 | 3 | 4 -> "Few"
| x ? (5..9).contains x -> "Several"
| x ? (10..19).contains x -> "Pack"
| _ -> "Lots"
return ans
}

9
tests/memory.lang Normal file
View file

@ -0,0 +1,9 @@
struct StructWithRef =
& @Int._ // unique pointer to any-sized array (default size is zero ??)
decl test_memory : Unit -> Unit
def test_memory = {
const @unique_ref1 <- @5 // move unique reference
var @unique_ref2 <- @(Array.of 1 2 3)
// ?? reference to constant value ??
}

20
tests/namespaces.lang Normal file
View file

@ -0,0 +1,20 @@
namespace Namespace {
decl something : Unit
}
namespace Array 'A {
decl something : Unit
// "static methods" of Array 'a class
}
namespace Array ('A : #Copy) {
decl something : Unit
// "static methods" of Array 'a with "copyable" 'a
}
namespace var a : Array ('A : #Copy) {
decl something : Unit
// "methods" of Array 'a (a as array instance) with "copyable" 'a
}
// ?? what to do with const/public/... methods ??

View file

@ -0,0 +1,5 @@
class (FixedArray : #Ord) 'A : (a : Int) =
& size(a) : Int // ?? const ??
& @[] : @'A.a
// ?? not shure about array definition ??

38
tests/partitions.lang Normal file
View file

@ -0,0 +1,38 @@
// partition DOC { // or .doc.lang filename
// // ...
// }
// ?? separated doc ??
partition TEST { // or .test.lang filename
decl something : Unit
}
partition INTERFACE { // or .interface.lang filename
decl something : Unit
}
partition CORE { // or .core.lang filename
decl something : Unit
}
partition LIB { // or .lib.lang filename
decl something : Unit
}
partition MODULE { // or .module.lang filename
decl something : Unit
}
// maybe another name for partition
partition EXE { // or .exe.lang filename
decl something : Unit
}
// partition CONFIG { // or .config.lang filename
// decl something : Unit
// }
// ?? config is one of the partitions ??
// ?? maybe more ??

12
tests/tuples.lang Normal file
View file

@ -0,0 +1,12 @@
decl test_tuples : Unit -> Unit
def test_tuples = {
var tuple1 = & "a" & 2 & "hello"
const & t1 & t2 & t3 = f x
; tuple1.0 = "b"
}
// ??????????????????????????

7
tests/type_casting.lang Normal file
View file

@ -0,0 +1,7 @@
decl test_type_casting : Unit -> Unit
def test_type_casting = {
var x = y.as Int
var k = (f y x).as Float
}
// type casting is can be done by generic method "as"

36
tests/typeclasses.lang Normal file
View file

@ -0,0 +1,36 @@
typeclass #Copy =
& copy : #Copy -> #Copy
typeclass (#Ord : #Eq) =
& ( < ) : #Ord -> #Ord -> Bool
& ( > ) : #Ord -> #Ord -> Bool
& ( <= ) : #Ord -> #Ord -> Bool
& ( >= ) : #Ord -> #Ord -> Bool
typeclass (#D : #A #B #C) 'A 'B =
& do_something : Unit -> (& 'A & 'B)
typeclass #E 'A =
& do_something : Unit -> 'A
namespace const ord : #Ord {
def ( <= ) : a b = (a < b) || (a == b)
def ( > ) : a b = !(a <= b)
def ( >= ) : a b = !(a < b)
}
// === ?? dependent types ?? ===
//
// typeclass #F : (a : Int) (b : Int) =
// & do_something Int -> Int
//
// namespace (f : #F a b c) {
// require do_sometihng a = b
// }
//
// ===
// ?? operators over functions (without arguments, like "def <= = < || ==;") ??
// ?? define operators like OCaml ??
// ?? denote moved type ??
// ?? "trait" VS "typeclass" ??

14
tests/types.lang Normal file
View file

@ -0,0 +1,14 @@
alias T1 = Int;
type (T2 : #A #B #C);
// Define file level abstract type
T2 =
| Int
| Float
| Complex;
// Compile module (functions, types, ...) for T2 = Int, Float, Complex
// ?? file level <-> module level ??

22
tests/variants.lang Normal file
View file

@ -0,0 +1,22 @@
decl test_variants : Unit -> Unit
def test_variants = {
var variant1 = | 'a' | 2 | "hello"
var | val | err = f x // optional types for each
; val -> "something" // open variant as value in expr
; val -!> "nothing" // open variant as None in expr
; ?err // open variant as value, or return None (if possible), operator
match variant1 with
| 'a' -> "something"
| 2 -> "something"
| "hello" -> "something"
| a -> "Something"
| String.of str -> "something"
| Int.of i -> "someting"
| 11 -> "nothing"
}
// ???????????????????????