1 /**
2 This module implements script functions that are stored in the global namespace such as parseInt and isdefined.
3 
4 ────────────────────────────────────────────────────────────────────────────────
5 
6 Copyright (C) 2021 pillager86.rf.gd
7 
8 This program is free software: you can redistribute it and/or modify it under 
9 the terms of the GNU General Public License as published by the Free Software 
10 Foundation, either version 3 of the License, or (at your option) any later 
11 version.
12 
13 This program is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with 
18 this program.  If not, see <https://www.gnu.org/licenses/>.
19 */
20 module mildew.stdlib.global;
21 
22 import mildew.environment;
23 import mildew.interpreter;
24 import mildew.types;
25 
26 /**
27  * This is called by the interpreter's initializeStdlib method to store functions in the global namespace.
28  * Documentation for these functions can be found at https://pillager86.github.io/dmildew/
29  * Params:
30  *  interpreter = The Interpreter instance to load the functions into.
31  */
32 void initializeGlobalLibrary(Interpreter interpreter)
33 {
34     interpreter.forceSetGlobal("isdefined", new ScriptFunction("isdefined", &native_isdefined));
35     interpreter.forceSetGlobal("isFinite", new ScriptFunction("isFinite", &native_isFinite));
36     interpreter.forceSetGlobal("isNaN", new ScriptFunction("isNaN", &native_isNaN));
37     interpreter.forceSetGlobal("parseFloat", new ScriptFunction("parseFloat", &native_parseFloat));
38     interpreter.forceSetGlobal("parseInt", new ScriptFunction("parseInt", &native_parseInt));
39 }
40 
41 //
42 // Global method implementations
43 //
44 
45 private ScriptAny native_isdefined(Environment env, 
46                                    ScriptAny* thisObj, 
47                                    ScriptAny[] args, 
48                                    ref NativeFunctionError nfe)
49 {
50     if(args.length < 1)
51         return ScriptAny(false);
52     auto varToLookup = args[0].toString();
53     return ScriptAny(env.variableOrConstExists(varToLookup));
54 }
55 
56 private ScriptAny native_isFinite(Environment env, ScriptAny* thisObj, 
57                                   ScriptAny[] args, ref NativeFunctionError nfe)
58 {
59     import std.math: isFinite;
60     if(args.length < 1)
61         return ScriptAny.UNDEFINED;
62     if(!args[0].isNumber)
63         return ScriptAny.UNDEFINED;
64     immutable value = args[0].toValue!double;
65     return ScriptAny(isFinite(value));
66 }
67 
68 private ScriptAny native_isNaN(Environment env, ScriptAny* thisObj,
69                                ScriptAny[] args, ref NativeFunctionError nfe)
70 {
71     import std.math: isNaN;
72     if(args.length < 1)
73         return ScriptAny.UNDEFINED;
74     if(!args[0].isNumber)
75         return ScriptAny(true);
76     immutable value = args[0].toValue!double;
77     return ScriptAny(isNaN(value));
78 }
79 
80 private ScriptAny native_parseFloat(Environment env, ScriptAny* thisObj,
81                                     ScriptAny[] args, ref NativeFunctionError nfe)
82 {
83     import std.conv: to, ConvException;
84     if(args.length < 1)
85         return ScriptAny(double.nan);
86     auto str = args[0].toString();
87     try 
88     {
89         immutable value = to!double(str);
90         return ScriptAny(value);
91     }
92     catch(ConvException)
93     {
94         return ScriptAny(double.nan);
95     }
96 }
97 
98 private ScriptAny native_parseInt(Environment env, ScriptAny* thisObj,
99                                   ScriptAny[] args, ref NativeFunctionError nfe)
100 {
101     import std.conv: to, ConvException;
102     if(args.length < 1)
103         return ScriptAny.UNDEFINED;
104     auto str = args[0].toString();
105     immutable radix = args.length > 1 ? args[1].toValue!int : 10;
106     try 
107     {
108         immutable value = to!long(str, radix);
109         return ScriptAny(value);
110     }
111     catch(ConvException)
112     {
113         return ScriptAny.UNDEFINED;
114     }
115 }