descriptionnone
ownersigint@posteo.de
last changeSun, 7 Apr 2024 19:14:48 +0000 (7 21:14 +0200)
content tags
add:
README.txt
splendini
=========

splendini is a programing language. Here is a sample session; building instructions are further down:


1 : 1
1=> 1

2 : Type(1)
2=> MInt

3 : a
3=> a

4 : Type(a)
4=> Symbol

5 : "hello world"
5=> "hello world"

6 : Type("hello world")
6=> String

7 : Type(Type(1))
7=> Symbol

8 : Type(Type(a))
8=> Symbol

9 : Type(Type("hello world"))
9=> Symbol

10 : f(a,1)
10=> f(a, 1)

11 : Type(f(a,1))
11=> f

12 : 1.1
12=> 1.100000000000000

13 : Type(1.1)
13=> MReal

14 : Type(a)
14=> Symbol

15 : Set(a, 1.1)
15=> 1.100000000000000

16 : a
16=> 1.100000000000000

17 : Type(a)
17=> MReal

18 : Type(Quote(a))
18=> Symbol

19 : Add(1,1)
19=> 2

20 : Type(Add(1,1))
20=> MInt

21 : Add(1,1.)
21=> 2.000000000000000

22 : Type(Add(1,1.))
22=> MReal

23 : Function(x, Add(x,1))
23=> Function(List(x), Add(x, 1))

24 : Type(Function(x, Add(x,1)))
24=> Function

25 : Set(f, Function(x, Add(x,1)))
25=> Function(List(x), Add(x, 1))

26 : f(1)
26=> 2

27 : Function(x, Add(x,1))(1)
27=> 2

28 : IsSame(1,1)
28=> True

29 : IsSame(a,a)
29=> True

30 : IsSame(a,b)
30=> False

31 : IsSame(Type(a),Type(b))
31=> False

32 : a
32=> 1.100000000000000

33 : b
33=> b

34 : Quote(a)
34=> a

35 : IsSame(Type(Quote(a)),Type(b))
35=> True

36 : If(True, "yes", "no")
36=> "yes"

37 : If(False, "yes", "no")
37=> "no"

38 : If(True, 1)
38=> 1

39 : If(False, 1)
39=> Null

40 : test
40=> test

41 : Type(test)
41=> Symbol

42 : If(test, 1)
42=> If(test, 1)

43 : If(test, 1, 2)
43=> If(test, 1, 2)

44 : If(test, 1, 2, 3)
44=> 3

45 : And(True, False)
45=> False

46 : Or(True, False)
46=> True

47 : Not(True)
47=> False

48 : Sequence(Set(a,0), Set(a, Add(a, 2)), a)
48=> 2

49 : Length(g(1,2,3))
49=> 3

50 : Length("Hello")
50=> 5

51 : Part(g(1,2,3), 1)
51=> 1

52 : Part(g(1,2,3), -1)
52=> 3

53 : Part(g(1,2,3), 0)
53=> g

54 : Set(a,0)
54=> 0

55 : Clear(a)
55=> 0

56 : a
56=> a

57 : Type(a)
57=> Symbol

58 : Set(a,0)
58=> 0

59 : Loop(Set(a, Add(a, 2)), List(10))
59=> Null

60 : a
60=> 20

61 : Timing(Loop(Set(a, Add(a, 2)), List(1000000)))
61=> List(0.805185079574585, Null)

62 : a
62=> 2000020

63 : Done




Some nice stuff:
================


1 : Set(f, Function(a, If(Not(IsSymbol(a)), Quote(f)(a), Print("Hi");a)))
1=> InterpretedFunction(List(a), If(Not(IsSymbol(a)), Quote(f)(a), Sequence(Print("Hi"), a)), StaticScope)

2 : f(sym)
Hi
2=> sym

3 : f(a)
Hi
3=> a



Closuers (Let):
=================

1 : {inc, dec} = Let({{b, 10}}, {Function({}, SetGlobal(b, b + 1)), Function({}, SetGlobal(b, b + -1))})
1=> List(Function(List(), SetGlobal(b, Add(b, 1)), StaticScope), Function(List(), SetGlobal(b, Add(b, -1)), StaticScope))

2 : inc()
2=> 11

3 : inc()
3=> 12

4 : dec()
4=> 11

5 : dec()
5=> 10

6 : dec()
6=> 9

------------


1 : i=0;j=0; Block({{i,1}}, Print(i); Print(j); i = 2; j = 2; Print(i); Print(j)); {i,j}
1
0
2
2
1=> List(0, 2)

% Block[{{var1, val1},..}, body]
% Block works by temprarily blocking all variables var1.. given and uses the value val1 in place. Also Block does not scope any variables in it's body (as does Let) except those given in var1...


------------

24 : i=0;{Table(i, {i, 1, 2}),i}
24=> List(List(1, 2), 0)

25 : j=0;{Table(j=i, {i, 1, 2}),i}
25=> List(List(1, 2), 0)

26 : j
26=> 2

% Table/Loop use Block for scoping the itator variable.

----------------


1 : i = 0; Let({},i=1)
1=> 1

2 : i
2=> 0

3 : i = 0; Let({},Set(i,1,GlobalFrame))
3=> 1

4 : i
4=> 1

5 : i = 0; Let({}, Let({{frame, Context()}}, Set(i,1, frame)); i)
5=> 1

6 : i
6=> 0

7 : i = 0; Let({}, Let({},SetGlobal(i,1)) )
7=> 1

8 : i
8=> 1

% the difference between SetGlobal and Set with a context is that SetGlobal walks 
% up the frames, looks for the variable name and sets it's value (scheme set!).
% Set sets the value of the variable in a context specified. 
% SetGlobal and Set with a context are also useful within a Function.

Let over Lambda over Let over Lambda:
======================================

(http://www.letoverlambda.com/textmode.cl/guest/chap2.html#sec_4, Doug Hoyte)

1 : {togle, counterClass} = Let(
	{{direction, "up"}},
	toggleCounter = Function({},
		SetGlobal(direction, If(direction === "up", "down", "up"))
	);
	counterClass = Let(
		{{counter, 0}},
		Function({},
			SetGlobal(counter, If(direction === "up",
				counter + 1,
				counter + -1
			))
		)
	);
	{toggleCounter, counterClass}
)

1=> List(Function(List(), Set(direction, If(IsSame(direction, "up"), "down", "up")), StaticScope), Function(List(), If(IsSame(direction, "up"), Set(counter, Add(counter, 1)), Set(counter, Add(counter, -1))), StaticScope))

2 : counterClass()
2=> 1

3 : counterClass()
3=> 2

4 : counterClass()
4=> 3

5 : togle()
5=> "down"

6 : counterClass()
6=> 2

7 : counterClass()
7=> 1

8 : counterClass()
8=> 0

9 : counterClass()
9=> -1

10 : togle()
10=> "up"

11 : counterClass()
11=> 0

12 : counterClass()
12=> 1



Tailrecursive :
===============

1 : Import(Load(ToFileName({"Scripts", "NumberTheory.spl"})))
1=> List(GoldenRatio, Fibonacci)

2 : Timing(Fibonacci(100000);)
2=> List(1.107151985168457, Null)

Set(fib,
        Function(
            List(n, i, f0, f1),
            If( Equal(i, n), 
                f0,
                fib(n, Add(i, 1), f1, Add(f0, f1))
            )
        )
    )

Set(Fibonacci,
    Function(
        n,
        %If( And( IsInteger(n), IsPositive(n)),
        If( And( IsNumberExact(n), GreaterEqual(n, 0)),
            fib(n, 0, 0, 1)
        ,
            Quote(Fibonacci)(n)
        )
    )
)   

Load Library Functions:
=======================
/* example_dll.h
#include "uex.h"

extern ue_p pfTest(ue_p state);
*/
/* example_dll.c
#include "example_dll.h"

ue_p pfTest(const ue_p state) {
    ue_p u = ue_mk_String("Hello World!");
    return u;
}
*/

//gcc -c -I/home/sigint/git/splendini/uexLib -Wall -Werror -fpic example_dll.c
//gcc -shared -o libexample_dll.so example_dll.o

1 : Test = LoadLibraryFunction("pfTest", "/home/sigint/git/buildSpl/libexample_dll.so")
1=> LibraryFunction("pfTest", "/home/sigint/git/buildSpl/libexample_dll.so")

2 : Test()
2=> "Hello World!"


OptimizeExpressions:
====================
1 : Timing(Table(Add(i,1),{i,1,100000});)
1=> List(0.191010951995850, Null)

2 : oe = OptimizeExpression(Table(Add(i,1),{i,1,100000}))
2=> Table(Add(i, 1), List(i, 1, 100000))

3 : Timing(Evaluate(oe);)
3=> List(0.120177984237671, Null)

OptimizeExpression works by replacing the symbol Add with the actual
system function Add and thus save the lookup of the code in every iteration.


Memorization:
=============
1 : fib = Function(n, If(n <= 2, 1, fib(n + -1) + fib(n + -2)))
1=> InterpretedFunction(List(n), If(LessEqual(n, 2), 1, Add(fib(Add(n, -1)), fib(Add(n, -2)))), StaticScope, Frame$313)

2 : Timing(fib(24))
2=> List(0.708318948745728, 46368)

3 : Timing(fib(23))
3=> List(0.445200204849243, 28657)

4 : memo = Function(fn, Let({ht = LookupData({{},{}}, False)}, Function(key, val = LookupDataFind(ht, key); If(val=!=False, val, LookupDataAdd(ht, {key, fn(key)})))));

5 : fib = memo(fib)
5=> InterpretedFunction(List(key), Sequence(Set(val, LookupDataFind(ht, key)), If(IsNotSame(val, False), val, LookupDataAdd(ht, List(key, fn(key))))), StaticScope, Frame$316)

6 : Timing(fib(24))
6=> List(0.004889965057373, 46368)

7 : Timing(fib(23))
7=> List(0.000065088272095, 28657)

8 : memoInspect = Function(fn, Let({ht = LookupData({{},{}}, False)}, Function(key, val = LookupDataFind(ht, key); If(val=!=False, val, r = LookupDataAdd(ht, {key, fn(key)}); Print(ht);r))));

9 : fib = Function(n, If(n <= 2, 1, fib(n + -1) + fib(n + -2)))
9=> InterpretedFunction(List(n), If(LessEqual(n, 2), 1, Add(fib(Add(n, -1)), fib(Add(n, -2)))), StaticScope, Frame$318)

10 : fib = memoInspect(fib)
10=> InterpretedFunction(List(key), Sequence(Set(val, LookupDataFind(ht, key)), If(IsNotSame(val, False), val, Sequence(Sequence(Set(r, LookupDataAdd(ht, List(key, fn(key)))), Print(ht)), r))), StaticScope, Frame$320)

11 : fib(10)
LookupData(List(List(2), List(1)), False)
LookupData(List(List(2, 1), List(1, 1)), False)
LookupData(List(List(2, 1, 3), List(1, 1, 2)), False)
LookupData(List(List(2, 1, 3, 4), List(1, 1, 2, 3)), False)
LookupData(List(List(2, 1, 3, 4, 5), List(1, 1, 2, 3, 5)), False)
LookupData(List(List(2, 1, 3, 4, 5, 6), List(1, 1, 2, 3, 5, 8)), False)
LookupData(List(List(2, 1, 3, 4, 5, 6, 7), List(1, 1, 2, 3, 5, 8, 13)), False)
LookupData(List(List(2, 1, 3, 4, 5, 6, 7, 8), List(1, 1, 2, 3, 5, 8, 13, 21)), False)
LookupData(List(List(2, 1, 3, 4, 5, 6, 7, 8, 9), List(1, 1, 2, 3, 5, 8, 13, 21, 34)), False)
LookupData(List(List(2, 1, 3, 4, 5, 6, 7, 8, 9, 10), List(1, 1, 2, 3, 5, 8, 13, 21, 34, 55)), False)
11=> 55

12 : fib(9)
12=> 34

% A function that is implemented with sub functions (e.g. system Fibonacci) can only cache function calls but not self calls of internal functions.

13 : Fibonacci = memoInspect( Fibonacci)
13=> InterpretedFunction(List(key), Sequence(Set(val, LookupDataFind(ht, key)), If(IsNotSame(val, False), val, Sequence(Sequence(Set(r, LookupDataAdd(ht, List(key, fn(key)))), Print(ht)), r))), StaticScope, Frame$322)

14 : Fibonacci(10)
LookupData(List(List(10), List(55)), False)
14=> 55

15 : Fibonacci(10)
15=> 55

16 : Fibonacci(9)
LookupData(List(List(10, 9), List(55, 34)), False)
16=> 34



Macros:
========
$ Maxros do two things: 1) they transform code 2) the transformed code is evaluated.
$ Since this functionality is available already there is no special Macro command.
$ The transformation function (i.e. the macro) should have a Quote attribute.
$ When you call the tranformation function on arguments the transformed code is
$ emitted. The code then is evaluated.

1 : when = Function({test, body}, Quote(If)(test, body));

2 : AttributesAdd(when, QuoteAll);

3 : when(False, Print("Should not print"); 1)
3=> If(False, Sequence(Print("Should not print"), 1))

4 : Evaluate(when(False, Print("Should not print"); 1) )

5 : when(True, Print("Should print"); 1)
5=> If(True, Sequence(Print("Should print"), 1))

6 : Evaluate( when(True, Print("Should print"); 1) )
Should print
6=> 1

$ Second example:
1 : let = Function({bindings, body},
	Quote(Apply)(
		Quote(Function)(Map(Function(x, Part(x,1)), bindings), body),
		Map(Function(x, Part(x,2)), bindings)
	)
);
AttributesAdd(let, QuoteAll);

2 : let({{x,1},{y,1}},x+y)
2=> Apply(Function(List(x, y), Add(x, y)), List(1, 1))

3 : Evaluate(let({{x,1},{y,1}},x+y))
3=> 2

4 : {x,y}
4=> List(x, y)

5 : w = let({{b,100}}, Function(a, SetGlobal(b, a+b)))
5=> Apply(Function(List(b), Function(a, SetGlobal(b, Add(a, b)))), List(100))

6 : w = Evaluate(let({{b,100}}, Function(a, SetGlobal(b, a+b))))
6=> InterpretedFunction(List(a), SetGlobal(b, Add(a, b)), StaticScope, Frame$154)

7 : w(1)
7=> 101

8 : w(10)
8=> 111

9 : w(-100)
9=> 11

% writinng this in a set of functions:

1 : Macro = Function({macrofun}, MacroData(AttributesAdd(macrofun, QuoteAll)));

2 : MacroExpand = Function(md, Apply(md[0][1], md));

3 : MacroEvaluate = Function(md, Evaluate(MacroExpand(md)));

4 : let = Macro(
	Function({bindings, body},
		Quote(Apply)(
			Quote(Function)(Map(Function(x, Part(x,1)), bindings), body),
			Map(Function(x, Part(x,2)), bindings)
		)
	)
	);

5 : MacroExpand(let({{x,1},{y,1}}, x+y))
5=> Apply(Function(List(x, y), Add(x, y)), List(1, 1))

6 : MacroEvaluate(let({{x,1},{y,1}}, x+y))
6=> 2


Building splendini:
--------------------
This is documented in the build.OSNAME files


Run test suite:
---------------
cmake -DCMAKE_BUILD_TYPE=Debug ../splendini/
make
make test

Code coverage (after 'make test'):
----------------------------------
ctest -D ExperimentalCoverage

for a single file (e.g.):

gcov uexLib/CMakeFiles/uexLib.dir/uex.c.o


Splint:
-------
splint -memchecks -I/usr/local/include -I./uexLib/ -I./uexLanguage/  uexLib/*.c uexLanguage/*.c main.c

valgrind:
---------
valgrind --track-origins=yes --leak-check=full --show-reachable=yes --suppressions=../splendini/boehm-gc.suppressions  ./splendiniCore test.spl >& vlgTest

cat test.spl 
done
shortlog
2024-04-07 sigintCleanupmaster
2024-04-07 sigintRemoves -fprofile-arcs -ftest-coverage - this has issue...
2024-04-06 sigintReorgnized directory structure and file names.
2024-03-30 sigintBreaks out tensors
2024-03-30 sigintBreaks out numbers
2024-03-30 sigintBreaks out utilities.
2024-03-30 sigintAdds a 'build' directory to .gitignore
2024-03-18 sigint2-arg math functions are no longer listable:
2024-03-13 sigintFixes a warning message.
2024-03-12 sigintChanges to get splendini to compile again.
2022-08-28 sigintFixes typo.
2022-08-28 sigintFixes potential fall through case.
2022-08-28 sigintChanges abs to labs - might need a change on 32 bit.
2022-08-28 sigintRequire CMake version 3.0
2019-10-19 sigintFixes typo.
2018-12-16 sigintRemoves unused variables
...
heads
2 weeks ago master
6 years ago dev_macro
6 years ago dev_termux
6 years ago dev_flatEnv
8 years ago dev_open
8 years ago dev_iterator