-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathBuiltins.cs
124 lines (122 loc) · 4 KB
/
Builtins.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using DtxCS.DataTypes;
namespace DtxCS
{
/// <summary>
/// Builtin functions, in case I end up writing an interpreter.
/// </summary>
static class Builtins
{
public static Dictionary<DataSymbol, Func<DataCommand, DataNode>> Funcs { get; }
static Builtins()
{
Funcs = new Dictionary<DataSymbol, Func<DataCommand, DataNode>>();
Funcs.Add(DataSymbol.Symbol("abs"), Abs);
Funcs.Add(DataSymbol.Symbol("+"), Add);
Funcs.Add(DataSymbol.Symbol("+="), AddEq);
Funcs.Add(DataSymbol.Symbol("&"), BitAnd);
Funcs.Add(DataSymbol.Symbol("append_str"), AppendStr);
Funcs.Add(DataSymbol.Symbol("assign"), Assign);
Funcs.Add(DataSymbol.Symbol("clamp"), Clamp);
Funcs.Add(DataSymbol.Symbol("--"), Dec);
Funcs.Add(DataSymbol.Symbol("/"), Divide);
Funcs.Add(DataSymbol.Symbol("="), Eq);
Funcs.Add(DataSymbol.Symbol("++"), Inc);
Funcs.Add(DataSymbol.Symbol(">"), Gt);
Funcs.Add(DataSymbol.Symbol("<"), Lt);
Funcs.Add(DataSymbol.Symbol("-"), Subtract);
Funcs.Add(DataSymbol.Symbol("if"), If);
}
static DataNode Abs(DataCommand input)
{
var args = input.EvalAll();
return new DataAtom(Math.Abs(args.Number(1)));
}
static DataNode Add(DataCommand input)
{
var args = input.EvalAll();
if(args.Node(1).Type == DataType.INT && args.Node(2).Type == DataType.INT)
{
return new DataAtom(args.Int(1) + args.Int(2));
}
return new DataAtom(args.Number(1) + args.Number(2));
}
static DataNode AddEq(DataCommand input)
{
var args = input.EvalAll();
return new DataAtom(args.Number(1) + args.Number(2));
}
static DataNode BitAnd(DataCommand input)
{
var args = input.EvalAll();
return new DataAtom(args.Int(1) & args.Int(2));
}
static DataNode AppendStr(DataCommand input)
{
var args = input.EvalAll();
return new DataAtom(args.String(1) + args.String(2));
}
static DataNode Assign(DataCommand input)
{
input.Var(1).Value = input.Node(2).Evaluate();
return input.Var(1).Value;
}
static DataNode Clamp(DataCommand input)
{
var args = input.EvalAll();
float f1 = args.Number(1), f2 = args.Number(2), f3 = args.Number(3);
return new DataAtom(f1 > f3 ? f3 : f1 < f2 ? f1 : f2);
}
static DataNode Dec(DataCommand input)
{
DataAtom a = input.Var(1).Value as DataAtom;
input.Var(1).Value = new DataAtom(a.Int - 1);
return input.Var(1).Value;
}
static DataNode Divide(DataCommand input)
{
var args = input.EvalAll();
return new DataAtom(args.Number(1) / args.Number(2));
}
static DataNode Eq(DataCommand input)
{
var args = input.EvalAll();
return new DataAtom(args.Node(1) == args.Node(2) ? 1 : 0);
}
static DataNode Gt(DataCommand input)
{
var args = input.EvalAll();
return new DataAtom(args.Number(1) > args.Number(2) ? 1 : 0);
}
static DataNode Inc(DataCommand input)
{
DataAtom a = input.Var(1).Value as DataAtom;
input.Var(1).Value = new DataAtom(a.Int + 1);
return input.Var(1).Value;
}
static DataNode Lt(DataCommand input)
{
var args = input.EvalAll();
return new DataAtom(args.Number(1) < args.Number(2) ? 1 : 0);
}
static DataNode Subtract(DataCommand input)
{
var args = input.EvalAll();
if (args.Node(1).Type == DataType.INT && args.Node(2).Type == DataType.INT)
{
return new DataAtom(args.Int(1) - args.Int(2));
}
return new DataAtom(args.Number(1) - args.Number(2));
}
static DataNode If(DataCommand input)
{
if ((input.Children[1].Evaluate() as DataAtom).Int == 0)
{
return input.Children[3].Evaluate();
}
return input.Children[2].Evaluate();
}
}
}