1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.millscript.millscript.functions;
23
24 import org.millscript.commons.alert.alerts.ClassNotFoundAlert;
25 import org.millscript.millscript.alert.Alerts;
26 import org.millscript.millscript.alert.Phases;
27 import org.millscript.millscript.vm.Machine;
28
29 import java.lang.reflect.Constructor;
30 import java.util.Arrays;
31
32 /**
33 * This class implements the MillScript <code>javaConstructor</code> function.
34 */
35 public class JavaConstructorFunction extends Function {
36
37 /**
38 * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
39 */
40 @Override
41 public void apply( final Machine mc, final int nargs ) {
42 if ( nargs <= 0 ) {
43 throw(
44 Alerts.eval(
45 "Calling javaConstructorFunction with no arguments",
46 "javaConstructorFunction requires at least the class name"
47 ).mishap()
48 );
49 }
50
51 int numArgs = nargs - 1;
52
53 try {
54
55 Class[] types = new Class[ numArgs ];
56 for ( int i = numArgs - 1; i >= 0; i-- ) {
57 types[ i ] = ParameterType.findClass( mc.popString() );
58 }
59 String className = mc.popString();
60 Class clss = Class.forName( className );
61
62 Constructor[] cons = clss.getConstructors();
63 for ( int k = 0; k < cons.length; k++ ) {
64 Constructor c = cons[ k ];
65 if ( Arrays.equals( c.getParameterTypes(), types ) ) {
66 mc.pushObject( new JConstructor( c ) );
67 return;
68 }
69 }
70
71 throw(
72 Alerts.eval(
73 "Cannot find matching constructor",
74 "There was no constructor with a matching type signature"
75 ).culprit( "class name", className ).mishap()
76 );
77
78 } catch ( ClassNotFoundException ex ) {
79 throw(
80 new ClassNotFoundAlert(
81 "The class name could not be resolved ($CLASSPATH problem?)"
82 ).culprit( "reason", ex.getMessage() ).setPhase( Phases.EVAL ).mishap()
83 );
84 }
85
86 }
87
88 }