1
2 /**
3 * Authors: k.inaba
4 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
5 *
6 * Runtime library for Polemy programming language.
7 */
8 module polemy.runtime;
9 import polemy._common;
10 import polemy.layer;
11 import polemy.failure;
12 import polemy.fresh;
13 import polemy.value;
14 import polemy.eval;
15 import std.stdio;
16 import std.random;
17
18 /// enroll the native implementations of primitive functions
19
20 void enrollRuntimeLibrary( Evaluator e )
21 {
22 // arithmetic operations
23 e.addPrimitive("+", ValueLayer,
24 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data + rhs.data);} );
25 e.addPrimitive("-", ValueLayer,
26 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data - rhs.data);} );
27 e.addPrimitive("*", ValueLayer,
28 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data * rhs.data);} );
29 e.addPrimitive("/", ValueLayer,
30 (IntValue lhs, IntValue rhs){
31 if( rhs.data == 0 )
32 throw genex!RuntimeException("division by 0");
33 return new IntValue(lhs.data / rhs.data);
34 });
35 e.addPrimitive("%", ValueLayer,
36 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data % rhs.data);} );
37 e.addPrimitive("||", ValueLayer,
38 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data!=0 || rhs.data!=0);} );
39 e.addPrimitive("&&", ValueLayer,
40 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data!=0 && rhs.data!=0);} );
41 // string operation(s)
42 e.addPrimitive("~", ValueLayer,
43 (Value lhs, Value rhs){return new StrValue(lhs.toString ~ rhs.toString);} );
44 // comparison
45 e.addPrimitive("<", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs < rhs);} );
46 e.addPrimitive(">", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs > rhs);} );
47 e.addPrimitive("<=", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs <= rhs);} );
48 e.addPrimitive(">=", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs >= rhs);} );
49 e.addPrimitive("==", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs == rhs);} );
50 e.addPrimitive("!=", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs != rhs);} );
51 // control flow
52 e.addPrimitive("if", ValueLayer, (IntValue x, FunValue ft, FunValue fe){
53 auto toRun = (x.data==0 ? fe : ft);
54 return toRun.invoke(ValueLayer, toRun.definitionContext(), null);
55 });
56 // type test
57 e.addPrimitive("_isint", ValueLayer,
58 (Value v){return new IntValue(cast(IntValue)v !is null);} );
59 e.addPrimitive("_isstr", ValueLayer,
60 (Value v){return new IntValue(cast(StrValue)v !is null);} );
61 e.addPrimitive("_isfun", ValueLayer,
62 (Value v){return new IntValue(cast(FunValue)v !is null);} );
63 e.addPrimitive("_isbot", ValueLayer,
64 (Value v){return new IntValue(cast(BottomValue)v !is null);} );
65 e.addPrimitive("_istbl", ValueLayer,
66 (Value v){return new IntValue(cast(Table)v !is null);} );
67 // table
68 e.addPrimitive(".", ValueLayer, (Table t, StrValue s){
69 if( t.has(s.data, ValueLayer) )
70 return t.get(s.data, ValueLayer);
71 throw genex!RuntimeException(text("table do not have the field ",s));
72 });
73 e.addPrimitive(".?", ValueLayer, (Table t, StrValue s){
74 return new IntValue(t.has(s.data, ValueLayer));
75 });
76 e.addPrimitive(".=", ValueLayer, (Table t, StrValue s, Value v){
77 auto t2 = new Table(t, Table.Kind.NotPropagateSet);
78 t2.set(s.data, ValueLayer, v);
79 return t2;
80 });
81 e.addPrimitive("{}", ValueLayer, (){
82 return new Table;
83 });
84 // IO and others
85 e.addPrimitive("print", ValueLayer, (Value a){ writeln(a); return a; });
86 e.addPrimitive("gensym", ValueLayer, (){ return new StrValue(freshVarName()); });
87 auto rand = Mt19937(unpredictableSeed);
88 e.addPrimitive("rand", ValueLayer, (IntValue n){
89 return new IntValue( uniform(0,cast(int)n.data.toInt(),rand) );
90 });
91 }