Skip to content

Commit cca1f92

Browse files
committed
Add remove and add procs to saved env
Fix docs and README
1 parent 24e9f06 commit cca1f92

File tree

6 files changed

+192
-50
lines changed

6 files changed

+192
-50
lines changed

README.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,46 @@ Extension designed to work [MSUnit](https://github.com/Anatoliy057/MSUnit)
77
***
88

99
## Closures
10-
A set of functions for manipulation of closures
10+
A set of functions for manipulation of closures.
1111

1212
### void set\_current\_env():
13-
Replaces the internal closing environment with the current one
13+
Replaces the internal closing environment with the current one.
1414

1515
***
1616

1717
## Echo
18-
A set of functions for logs
18+
A set of functions for logs.
1919

2020
### void print(message):
21-
Prints a message
21+
Prints a message.
2222

2323
### void println(message):
2424
Prints a message and then terminate the line.
2525

2626
***
2727

2828
## Environments
29-
A set of functions for environment
29+
A set of functions for environment.
3030

3131
### void remove\_env(id):
32-
Remove reference of environment by id
32+
Remove reference of environment by id.
3333

3434
### void save\_env(id):
35-
Save reference of environment by id
35+
Save reference of environment by id.
3636

3737
### void x\_replace\_procedure(id, proc, replacement):
38-
Swaps one procedure for another (or given closure) in a saved environment
38+
Swaps one procedure for another (or given closure) in a saved environment.
39+
40+
### void x_add_procedure(id, proc, [closure])
41+
Add procedure (or given closure as procedure named by procName) in a saved environment.
42+
43+
### boolean x_remove_procedure(id, proc)
44+
Remove procedure from a saved environment.
3945

4046
***
4147

4248
## Global
43-
A set of functions for globals
49+
A set of functions for globals.
4450

4551
### void x_set_extend_daemon_manager():
4652
Sets extend daemon manager, that clearing globals when threads deactivated.
@@ -52,10 +58,10 @@ ets automatically initialize globals for new threads.
5258
Returns whether globals for threads are automatically initialized.
5359

5460
### void keys\_globals():
55-
Return array of keys globals
61+
Return array of keys globals.
5662

5763
### void original\_export(key, value):
58-
Stores a value in the original global storage register (like "export".
64+
Stores a value in the original global storage register (like "export").
5965

6066
### mixed original\_import(key, [default]):
6167
This function likes "import" but imports a value from the original global value register.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package me.anatoliy57.chunit.core;
2+
3+
import com.laytonsmith.core.Procedure;
4+
import com.laytonsmith.core.constructs.CClosure;
5+
import com.laytonsmith.core.constructs.Target;
6+
import com.laytonsmith.core.environments.Environment;
7+
import com.laytonsmith.core.natives.interfaces.Mixed;
8+
9+
import java.util.Collections;
10+
import java.util.List;
11+
12+
public class ProcClosure extends Procedure implements Cloneable {
13+
14+
private final String name;
15+
private CClosure closure;
16+
17+
public ProcClosure(String name, CClosure closure, Target t) {
18+
super(name, null, Collections.EMPTY_LIST, null, t);
19+
20+
this.name = name;
21+
this.closure = closure;
22+
}
23+
24+
@Override
25+
public Mixed execute(List<Mixed> args, Environment oldEnv, Target t) {
26+
Mixed[] values = new Mixed[args.size()];
27+
args.toArray(values);
28+
return closure.executeCallable(values);
29+
}
30+
31+
@Override
32+
public Procedure clone() throws CloneNotSupportedException {
33+
ProcClosure clone = (ProcClosure)super.clone();
34+
35+
if(closure != null) {
36+
clone.closure = this.closure.clone();
37+
}
38+
39+
return clone;
40+
}
41+
42+
@Override
43+
public void definitelyNotConstant() {
44+
super.definitelyNotConstant();
45+
}
46+
47+
@Override
48+
public String getName() {
49+
return name;
50+
}
51+
}

src/main/java/me/anatoliy57/chunit/functions/Closures.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
public class Closures {
1717

1818
public static String docs() {
19-
return "A set of functions for manipulation of closures";
19+
return "A set of functions for manipulation of closures.";
2020
}
2121

2222
@api
@@ -34,7 +34,7 @@ public Integer[] numArgs() {
3434

3535
@Override
3636
public String docs() {
37-
return "void {} Replaces the internal closing environment with the current one";
37+
return "void {} Replaces the internal closing environment with the current one.";
3838
}
3939

4040
@Override

src/main/java/me/anatoliy57/chunit/functions/Echo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
public class Echo {
1919
public static String docs() {
20-
return "A set of functions for logs";
20+
return "A set of functions for logs.";
2121
}
2222

2323
public static BufferedWriter out;
@@ -42,7 +42,7 @@ public Integer[] numArgs() {
4242
}
4343

4444
public String docs() {
45-
return "void {message} Prints a message";
45+
return "void {message} Prints a message.";
4646
}
4747

4848
public Class<? extends CREThrowable>[] thrown() {

src/main/java/me/anatoliy57/chunit/functions/Environments.java

Lines changed: 117 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package me.anatoliy57.chunit.functions;
22

33
import com.laytonsmith.annotations.api;
4+
import com.laytonsmith.core.ArgumentValidation;
45
import com.laytonsmith.core.Globals;
56
import com.laytonsmith.core.MSVersion;
67
import com.laytonsmith.core.Procedure;
@@ -13,13 +14,15 @@
1314
import com.laytonsmith.core.exceptions.CRE.CREThrowable;
1415
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
1516
import com.laytonsmith.core.functions.AbstractFunction;
17+
import com.laytonsmith.core.functions.ArrayHandling;
1618
import com.laytonsmith.core.natives.interfaces.Mixed;
19+
import me.anatoliy57.chunit.core.ProcClosure;
1720

1821
import java.util.*;
1922

2023
public class Environments {
2124
public static String docs() {
22-
return "A set of functions for environment";
25+
return "A set of functions for environment.";
2326
}
2427

2528
public static final Map<String, Environment> environmentMap = new HashMap<>();
@@ -39,7 +42,7 @@ public Integer[] numArgs() {
3942
}
4043

4144
public String docs() {
42-
return "void {id} Save reference of environment by id";
45+
return "void {id} Save reference of environment by id.";
4346
}
4447

4548
public Class<? extends CREThrowable>[] thrown() {
@@ -83,7 +86,7 @@ public Integer[] numArgs() {
8386
}
8487

8588
public String docs() {
86-
return "void {id} Remove reference of environment by id";
89+
return "void {id} Remove reference of environment by id.";
8790
}
8891

8992
public Class<? extends CREThrowable>[] thrown() {
@@ -127,7 +130,7 @@ public Integer[] numArgs() {
127130
}
128131

129132
public String docs() {
130-
return "void {id, proc, replacement} Swaps one procedure for another (or given closure) in a saved environment";
133+
return "void {id, proc, replacement} Swaps one procedure for another (or given closure) in a saved environment.";
131134
}
132135

133136
public Class<? extends CREThrowable>[] thrown() {
@@ -156,7 +159,7 @@ public Mixed exec(Target t, Environment env, Mixed... args) throws ConfigRuntime
156159
Map<String, Procedure> procedures = global.GetProcs();
157160

158161
if(!procedures.containsKey(proc)) {
159-
throw new CREInvalidProcedureException("Unknown procedure \"" + proc + '"', t);
162+
throw new CREInvalidProcedureException("Unknown procedure \"" + proc + "\" in saved environment", t);
160163
}
161164

162165
Procedure val;
@@ -166,7 +169,7 @@ public Mixed exec(Target t, Environment env, Mixed... args) throws ConfigRuntime
166169
val = new ProcClosure(proc, (CClosure) replacement, t);
167170
} else {
168171
val = Optional.ofNullable(currentProcedures.get(replacement.val())).orElseThrow(() -> {
169-
throw new CREInvalidProcedureException("Unknown procedure \"" + replacement.val() + '"', t);
172+
throw new CREInvalidProcedureException("Unknown procedure \"" + replacement.val() + "\" in current environment", t);
170173
});
171174
}
172175

@@ -178,46 +181,128 @@ public Mixed exec(Target t, Environment env, Mixed... args) throws ConfigRuntime
178181
public Boolean runAsync() {
179182
return null;
180183
}
184+
}
181185

182-
private static class ProcClosure extends Procedure implements Cloneable {
186+
@api
187+
public static class x_add_procedure extends AbstractFunction {
183188

184-
private final String name;
185-
private CClosure closure;
189+
public x_add_procedure() {
190+
}
186191

187-
public ProcClosure(String name, CClosure closure, Target t) {
188-
super(name, null, Collections.EMPTY_LIST, null, t);
192+
public String getName() {
193+
return "x_add_procedure";
194+
}
189195

190-
this.name = name;
191-
this.closure = closure;
192-
}
196+
public Integer[] numArgs() {
197+
return new Integer[]{2, 3};
198+
}
199+
200+
public String docs() {
201+
return "void {id, procName, [closure]} Add procedure (or given closure as procedure named by procName) in a saved environment.";
202+
}
203+
204+
public Class<? extends CREThrowable>[] thrown() {
205+
return new Class[]{CRECastException.class, CREInvalidProcedureException.class, CREIndexOverflowException.class};
206+
}
207+
208+
public boolean isRestricted() {
209+
return true;
210+
}
211+
212+
public MSVersion since() {
213+
return MSVersion.V3_0_2;
214+
}
193215

194-
@Override
195-
public Mixed execute(List<Mixed> args, Environment oldEnv, Target t) {
196-
Mixed[] values = new Mixed[args.size()];
197-
args.toArray(values);
198-
return closure.executeCallable(values);
216+
public Mixed exec(Target t, Environment env, Mixed... args) throws ConfigRuntimeException {
217+
String id = args[0].val();
218+
String proc = args[1].val();
219+
220+
Environment savedEnv;
221+
synchronized (environmentMap) {
222+
savedEnv = Optional.ofNullable(environmentMap.get(id)).orElseThrow(() -> {
223+
throw new CREIndexOverflowException("No environment with this id \""+id+"\" found", t);
224+
});
199225
}
226+
GlobalEnv global = savedEnv.getEnv(GlobalEnv.class);
227+
Map<String, Procedure> procedures = global.GetProcs();
200228

201-
@Override
202-
public Procedure clone() throws CloneNotSupportedException {
203-
ProcClosure clone = (ProcClosure)super.clone();
229+
if(procedures.containsKey(proc)) {
230+
throw new CREInvalidProcedureException("Procedure already exists \"" + proc + "\" in saved environment", t);
231+
}
204232

205-
if(closure != null) {
206-
clone.closure = this.closure.clone();
233+
Procedure val;
234+
if(args.length == 3) {
235+
if(!args[2].isInstanceOf(CClosure.TYPE)) {
236+
throw new CRECastException("Expecting a closure for argument 2", t);
207237
}
238+
CClosure closure = (CClosure) args[2];
239+
val = new ProcClosure(proc, closure, t);
240+
} else {
241+
Map<String, Procedure> currentProcedures = env.getEnv(GlobalEnv.class).GetProcs();
208242

209-
return clone;
243+
val = Optional.ofNullable(currentProcedures.get(proc)).orElseThrow(() -> {
244+
throw new CREInvalidProcedureException("Unknown procedure \"" + proc + "\" in current environment", t);
245+
});
210246
}
211247

212-
@Override
213-
public void definitelyNotConstant() {
214-
super.definitelyNotConstant();
215-
}
248+
procedures.put(proc, val);
216249

217-
@Override
218-
public String getName() {
219-
return name;
250+
return CVoid.VOID;
251+
}
252+
253+
public Boolean runAsync() {
254+
return null;
255+
}
256+
}
257+
258+
@api
259+
public static class x_remove_procedure extends AbstractFunction {
260+
261+
public x_remove_procedure() {
262+
}
263+
264+
public String getName() {
265+
return "x_remove_procedure";
266+
}
267+
268+
public Integer[] numArgs() {
269+
return new Integer[]{2};
270+
}
271+
272+
public String docs() {
273+
return "boolean {id, procName} Remove procedure from a saved environment.";
274+
}
275+
276+
public Class<? extends CREThrowable>[] thrown() {
277+
return new Class[]{CREIndexOverflowException.class};
278+
}
279+
280+
public boolean isRestricted() {
281+
return true;
282+
}
283+
284+
public MSVersion since() {
285+
return MSVersion.V3_0_2;
286+
}
287+
288+
public Mixed exec(Target t, Environment env, Mixed... args) throws ConfigRuntimeException {
289+
String id = args[0].val();
290+
String proc = args[1].val();
291+
292+
Environment savedEnv;
293+
synchronized (environmentMap) {
294+
savedEnv = Optional.ofNullable(environmentMap.get(id)).orElseThrow(() -> {
295+
throw new CREIndexOverflowException("No environment with this id \""+id+"\" found", t);
296+
});
220297
}
298+
GlobalEnv global = savedEnv.getEnv(GlobalEnv.class);
299+
Map<String, Procedure> procedures = global.GetProcs();
300+
301+
return CBoolean.get(procedures.remove(proc) != null);
302+
}
303+
304+
public Boolean runAsync() {
305+
return null;
221306
}
222307
}
223308
}

0 commit comments

Comments
 (0)