4 splendini is a programing language. Here is a sample session; building instructions are further down:
22 6 : Type("hello world")
31 9 : Type(Type("hello world"))
41 12=> 1.100000000000000
50 15=> 1.100000000000000
53 16=> 1.100000000000000
68 21=> 2.000000000000000
73 23 : Function(x, Add(x,1))
74 23=> Function(List(x), Add(x, 1))
76 24 : Type(Function(x, Add(x,1)))
79 25 : Set(f, Function(x, Add(x,1)))
80 25=> Function(List(x), Add(x, 1))
85 27 : Function(x, Add(x,1))(1)
97 31 : IsSame(Type(a),Type(b))
101 32=> 1.100000000000000
109 35 : IsSame(Type(Quote(a)),Type(b))
112 36 : If(True, "yes", "no")
115 37 : If(False, "yes", "no")
136 44 : If(test, 1, 2, 3)
139 45 : And(True, False)
148 48 : Sequence(Set(a,0), Set(a, Add(a, 2)), a)
151 49 : Length(g(1,2,3))
157 51 : Part(g(1,2,3), 1)
160 52 : Part(g(1,2,3), -1)
163 53 : Part(g(1,2,3), 0)
181 59 : Loop(Set(a, Add(a, 2)), List(10))
187 61 : Timing(Loop(Set(a, Add(a, 2)), List(1000000)))
188 61=> List(0.805185079574585, Null)
202 1 : Set(f, Function(a, If(Not(IsSymbol(a)), Quote(f)(a), Print("Hi");a)))
203 1=> InterpretedFunction(List(a), If(Not(IsSymbol(a)), Quote(f)(a), Sequence(Print("Hi"), a)), StaticScope)
218 1 : {inc, dec} = Let({{b, 10}}, {Function({}, SetGlobal(b, b + 1)), Function({}, SetGlobal(b, b + -1))})
219 1=> List(Function(List(), SetGlobal(b, Add(b, 1)), StaticScope), Function(List(), SetGlobal(b, Add(b, -1)), StaticScope))
239 1 : i=0;j=0; Block({{i,1}}, Print(i); Print(j); i = 2; j = 2; Print(i); Print(j)); {i,j}
246 % Block[{{var1, val1},..}, body]
247 % 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...
252 24 : i=0;{Table(i, {i, 1, 2}),i}
253 24=> List(List(1, 2), 0)
255 25 : j=0;{Table(j=i, {i, 1, 2}),i}
256 25=> List(List(1, 2), 0)
261 % Table/Loop use Block for scoping the itator variable.
266 1 : i = 0; Let({},i=1)
272 3 : i = 0; Let({},Set(i,1,GlobalFrame))
278 5 : i = 0; Let({}, Let({{frame, Context()}}, Set(i,1, frame)); i)
284 7 : i = 0; Let({}, Let({},SetGlobal(i,1)) )
290 % the difference between SetGlobal and Set with a context is that SetGlobal walks
291 % up the frames, looks for the variable name and sets it's value (scheme set!).
292 % Set sets the value of the variable in a context specified.
293 % SetGlobal and Set with a context are also useful within a Function.
295 Let over Lambda over Let over Lambda:
296 ======================================
298 (http://www.letoverlambda.com/textmode.cl/guest/chap2.html#sec_4, Doug Hoyte)
300 1 : {togle, counterClass} = Let(
302 toggleCounter = Function({},
303 SetGlobal(direction, If(direction === "up", "down", "up"))
308 SetGlobal(counter, If(direction === "up",
314 {toggleCounter, counterClass}
317 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))
357 1 : Import(Load(ToFileName({"Scripts", "NumberTheory.spl"})))
358 1=> List(GoldenRatio, Fibonacci)
360 2 : Timing(Fibonacci(100000);)
361 2=> List(1.107151985168457, Null)
368 fib(n, Add(i, 1), f1, Add(f0, f1))
376 %If( And( IsInteger(n), IsPositive(n)),
377 If( And( IsNumberExact(n), GreaterEqual(n, 0)),
385 Load Library Functions:
386 =======================
390 extern ue_p pfTest(ue_p state);
393 #include "example_dll.h"
395 ue_p pfTest(const ue_p state) {
396 ue_p u = ue_mk_String("Hello World!");
401 //gcc -c -I/home/sigint/git/splendini/uexLib -Wall -Werror -fpic example_dll.c
402 //gcc -shared -o libexample_dll.so example_dll.o
404 1 : Test = LoadLibraryFunction("pfTest", "/home/sigint/git/buildSpl/libexample_dll.so")
405 1=> LibraryFunction("pfTest", "/home/sigint/git/buildSpl/libexample_dll.so")
413 1 : Timing(Table(Add(i,1),{i,1,100000});)
414 1=> List(0.191010951995850, Null)
416 2 : oe = OptimizeExpression(Table(Add(i,1),{i,1,100000}))
417 2=> Table(Add(i, 1), List(i, 1, 100000))
419 3 : Timing(Evaluate(oe);)
420 3=> List(0.120177984237671, Null)
422 OptimizeExpression works by replacing the symbol Add with the actual
423 system function Add and thus save the lookup of the code in every iteration.
428 1 : fib = Function(n, If(n <= 2, 1, fib(n + -1) + fib(n + -2)))
429 1=> InterpretedFunction(List(n), If(LessEqual(n, 2), 1, Add(fib(Add(n, -1)), fib(Add(n, -2)))), StaticScope, Frame$313)
432 2=> List(0.708318948745728, 46368)
435 3=> List(0.445200204849243, 28657)
437 4 : memo = Function(fn, Let({ht = LookupData({{},{}}, False)}, Function(key, val = LookupDataFind(ht, key); If(val=!=False, val, LookupDataAdd(ht, {key, fn(key)})))));
440 5=> InterpretedFunction(List(key), Sequence(Set(val, LookupDataFind(ht, key)), If(IsNotSame(val, False), val, LookupDataAdd(ht, List(key, fn(key))))), StaticScope, Frame$316)
443 6=> List(0.004889965057373, 46368)
446 7=> List(0.000065088272095, 28657)
448 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))));
450 9 : fib = Function(n, If(n <= 2, 1, fib(n + -1) + fib(n + -2)))
451 9=> InterpretedFunction(List(n), If(LessEqual(n, 2), 1, Add(fib(Add(n, -1)), fib(Add(n, -2)))), StaticScope, Frame$318)
453 10 : fib = memoInspect(fib)
454 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)
457 LookupData(List(List(2), List(1)), False)
458 LookupData(List(List(2, 1), List(1, 1)), False)
459 LookupData(List(List(2, 1, 3), List(1, 1, 2)), False)
460 LookupData(List(List(2, 1, 3, 4), List(1, 1, 2, 3)), False)
461 LookupData(List(List(2, 1, 3, 4, 5), List(1, 1, 2, 3, 5)), False)
462 LookupData(List(List(2, 1, 3, 4, 5, 6), List(1, 1, 2, 3, 5, 8)), False)
463 LookupData(List(List(2, 1, 3, 4, 5, 6, 7), List(1, 1, 2, 3, 5, 8, 13)), False)
464 LookupData(List(List(2, 1, 3, 4, 5, 6, 7, 8), List(1, 1, 2, 3, 5, 8, 13, 21)), False)
465 LookupData(List(List(2, 1, 3, 4, 5, 6, 7, 8, 9), List(1, 1, 2, 3, 5, 8, 13, 21, 34)), False)
466 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)
472 % A function that is implemented with sub functions (e.g. system Fibonacci) can only cache function calls but not self calls of internal functions.
474 13 : Fibonacci = memoInspect( Fibonacci)
475 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)
478 LookupData(List(List(10), List(55)), False)
485 LookupData(List(List(10, 9), List(55, 34)), False)
492 $ Maxros do two things: 1) they transform code 2) the transformed code is evaluated.
493 $ Since this functionality is available already there is no special Macro command.
494 $ The transformation function (i.e. the macro) should have a Quote attribute.
495 $ When you call the tranformation function on arguments the transformed code is
496 $ emitted. The code then is evaluated.
498 1 : when = Function({test, body}, Quote(If)(test, body));
500 2 : AttributesAdd(when, QuoteAll);
502 3 : when(False, Print("Should not print"); 1)
503 3=> If(False, Sequence(Print("Should not print"), 1))
505 4 : Evaluate(when(False, Print("Should not print"); 1) )
507 5 : when(True, Print("Should print"); 1)
508 5=> If(True, Sequence(Print("Should print"), 1))
510 6 : Evaluate( when(True, Print("Should print"); 1) )
515 1 : let = Function({bindings, body},
517 Quote(Function)(Map(Function(x, Part(x,1)), bindings), body),
518 Map(Function(x, Part(x,2)), bindings)
521 AttributesAdd(let, QuoteAll);
523 2 : let({{x,1},{y,1}},x+y)
524 2=> Apply(Function(List(x, y), Add(x, y)), List(1, 1))
526 3 : Evaluate(let({{x,1},{y,1}},x+y))
532 5 : w = let({{b,100}}, Function(a, SetGlobal(b, a+b)))
533 5=> Apply(Function(List(b), Function(a, SetGlobal(b, Add(a, b)))), List(100))
535 6 : w = Evaluate(let({{b,100}}, Function(a, SetGlobal(b, a+b))))
536 6=> InterpretedFunction(List(a), SetGlobal(b, Add(a, b)), StaticScope, Frame$154)
547 % writinng this in a set of functions:
549 1 : Macro = Function({macrofun}, MacroData(AttributesAdd(macrofun, QuoteAll)));
551 2 : MacroExpand = Function(md, Apply(md[0][1], md));
553 3 : MacroEvaluate = Function(md, Evaluate(MacroExpand(md)));
556 Function({bindings, body},
558 Quote(Function)(Map(Function(x, Part(x,1)), bindings), body),
559 Map(Function(x, Part(x,2)), bindings)
564 5 : MacroExpand(let({{x,1},{y,1}}, x+y))
565 5=> Apply(Function(List(x, y), Add(x, y)), List(1, 1))
567 6 : MacroEvaluate(let({{x,1},{y,1}}, x+y))
573 This is documented in the build.OSNAME files
578 cmake -DCMAKE_BUILD_TYPE=Debug ../splendini/
582 Code coverage (after 'make test'):
583 ----------------------------------
584 ctest -D ExperimentalCoverage
586 for a single file (e.g.):
588 gcov uexLib/CMakeFiles/uexLib.dir/uex.c.o
593 splint -memchecks -I/usr/local/include -I./uexLib/ -I./uexLanguage/ uexLib/*.c uexLanguage/*.c main.c
597 valgrind --track-origins=yes --leak-check=full --show-reachable=yes --suppressions=../splendini/boehm-gc.suppressions ./splendiniCore test.spl >& vlgTest