/
SLFunctions.cs
88 lines (76 loc) · 3.28 KB
/
SLFunctions.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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MISP
{
public partial class Engine
{
internal static Scope CopyScope(Scope scope)
{
var r = new Scope();
foreach (var v in scope.variables)
r.variables.Add(v.Key, new ScriptList(v.Value[v.Value.Count - 1]));
return r;
}
private ScriptObject defunImple(Context context, ScriptList arguments, bool addToScope)
{
var functionName = ArgumentType<String>(arguments[0]);
ScriptList argumentInfo = null;
try
{
argumentInfo = ArgumentType<ScriptList>(arguments[1]);
}
catch (ScriptError e)
{
context.RaiseNewError(e.Message, context.currentNode);
return null;
}
var functionBody = ArgumentType<ScriptObject>(arguments[2]);
var newFunction = Function.MakeFunction(
functionName,
argumentInfo,
"Script-defined function",
functionBody,
CopyScope(context.Scope));
if (arguments[3] != null) newFunction["@help"] = ScriptObject.AsString(arguments[3]);
if (addToScope) (newFunction["declaration-scope"] as Scope).PushVariable(functionName, newFunction);
return newFunction;
}
private void SetupFunctionFunctions()
{
AddFunction("defun", "name arguments code",
(context, arguments) =>
{
var r = defunImple(context, arguments, false);
if (context.evaluationState == EvaluationState.Normal && !String.IsNullOrEmpty(r.gsp("@name")))
functions.Upsert(r.gsp("@name"), r);
return r;
},
Arguments.Mutator(Arguments.Lazy("name"), "(@identifier value)"),
Arguments.Mutator(Arguments.Lazy("arguments"), "(@lazy-list value)"),
Arguments.Lazy("code"),
Arguments.Optional("comment"));
AddFunction("lambda", "name arguments code",
(context, arguments) =>
{
return defunImple(context, arguments, false);
},
Arguments.Mutator(Arguments.Lazy("name"), "(@identifier value)"),
Arguments.Mutator(Arguments.Lazy("arguments"), "(@lazy-list value)"),
Arguments.Lazy("code"),
Arguments.Optional("comment"));
AddFunction("lfun", "Creates a local function. This is functionally equivilent to using 'let' to store a function in a local variable.",
(context, arguments) =>
{
var r = defunImple(context, arguments, true);
if (context.evaluationState == EvaluationState.Normal) context.Scope.PushVariable(r.gsp("@name"), r);
return r;
},
Arguments.Mutator(Arguments.Lazy("name"), "(@identifier value)"),
Arguments.Mutator(Arguments.Lazy("arguments"), "(@lazy-list value)"),
Arguments.Lazy("code"),
Arguments.Optional("comment"));
}
}
}