Revision | 98e39574361c4aea1fd6d134ffd6e66b6d09497d (tree) |
---|---|
Zeit | 2015-07-03 03:58:54 |
Autor | MirrgieRiana |
Commiter | MirrgieRiana |
7/3
@@ -2,7 +2,17 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.CardLayout; |
4 | 4 | import java.awt.Color; |
5 | +import java.io.BufferedReader; | |
6 | +import java.io.ByteArrayOutputStream; | |
7 | +import java.io.File; | |
8 | +import java.io.FileInputStream; | |
9 | +import java.io.FileOutputStream; | |
10 | +import java.io.InputStreamReader; | |
11 | +import java.io.PrintStream; | |
12 | +import java.util.function.Consumer; | |
13 | +import java.util.stream.Collectors; | |
5 | 14 | |
15 | +import javax.swing.JFileChooser; | |
6 | 16 | import javax.swing.JMenu; |
7 | 17 | import javax.swing.JMenuBar; |
8 | 18 | import javax.swing.JMenuItem; |
@@ -13,6 +23,7 @@ | ||
13 | 23 | import javax.swing.WindowConstants; |
14 | 24 | import javax.swing.event.DocumentEvent; |
15 | 25 | import javax.swing.event.DocumentListener; |
26 | +import javax.swing.filechooser.FileNameExtensionFilter; | |
16 | 27 | |
17 | 28 | import mirrg.compile.iodine.CompileResult; |
18 | 29 | import mirrg.compile.iodine.INode; |
@@ -22,6 +33,7 @@ | ||
22 | 33 | import mirrg.game.complexcanvas.wulfenite.script.ArgumentWulfeniteScriptValidate; |
23 | 34 | import mirrg.game.complexcanvas.wulfenite.script.IWulfeniteScript; |
24 | 35 | import mirrg.game.complexcanvas.wulfenite.script.WulfeniteScript; |
36 | +import mirrg.struct.hydrogen.Struct1; | |
25 | 37 | |
26 | 38 | public class FrameFormula extends FrameBase |
27 | 39 | { |
@@ -33,6 +45,9 @@ | ||
33 | 45 | protected JTextArea textAreaShow; |
34 | 46 | |
35 | 47 | protected String titleBase; |
48 | + protected boolean running = false; | |
49 | + protected File file = null; | |
50 | + protected boolean dirty = false; | |
36 | 51 | |
37 | 52 | public FrameFormula(INitrogenEventRegistry eventRegistry) |
38 | 53 | { |
@@ -42,6 +57,14 @@ | ||
42 | 57 | this.eventRegistry = eventRegistry; |
43 | 58 | } |
44 | 59 | |
60 | + public void updateTitle() | |
61 | + { | |
62 | + setTitle(titleBase | |
63 | + + (running ? " [コンパイル中]" : "") | |
64 | + + (file != null ? " - " + file.getName() : "") | |
65 | + + (dirty ? " *" : "")); | |
66 | + } | |
67 | + | |
45 | 68 | @Override |
46 | 69 | protected void initContents() |
47 | 70 | { |
@@ -51,6 +74,116 @@ | ||
51 | 74 | setJMenuBar(menuBar); |
52 | 75 | |
53 | 76 | { |
77 | + JMenu menu = new JMenu("ファイル(F)"); | |
78 | + menu.setMnemonic('F'); | |
79 | + menuBar.add(menu); | |
80 | + | |
81 | + Struct1<Consumer<File>> handlerFile = new Struct1<>(file2 -> { | |
82 | + this.file = file2; | |
83 | + }); | |
84 | + | |
85 | + { | |
86 | + JMenuItem menuItem = new JMenuItem("開く(O)"); | |
87 | + menuItem.setMnemonic('O'); | |
88 | + menu.add(menuItem); | |
89 | + | |
90 | + menuItem.addActionListener(event -> { | |
91 | + JFileChooser fileChooser = new JFileChooser(); | |
92 | + fileChooser.addChoosableFileFilter(new FileNameExtensionFilter( | |
93 | + "Wulfenite スクリプトファイル(*.wul)", "wul")); | |
94 | + fileChooser.setAcceptAllFileFilterUsed(true); | |
95 | + | |
96 | + int res = fileChooser.showOpenDialog(this); | |
97 | + if (res == JFileChooser.CANCEL_OPTION) { | |
98 | + textAreaShow.setText("ダイアログがキャンセルされました。"); | |
99 | + } else if (res == JFileChooser.ERROR_OPTION) { | |
100 | + textAreaShow.setText("ダイアログ上でエラーが発生しました。"); | |
101 | + } | |
102 | + | |
103 | + try (BufferedReader in = new BufferedReader( | |
104 | + new InputStreamReader( | |
105 | + new FileInputStream( | |
106 | + fileChooser.getSelectedFile())))) { | |
107 | + String data = in.lines().collect(Collectors.joining("\n")); | |
108 | + textAreaSource.setText(data); | |
109 | + update(); | |
110 | + | |
111 | + dirty = false; | |
112 | + handlerFile.x.accept(fileChooser.getSelectedFile()); | |
113 | + updateTitle(); | |
114 | + | |
115 | + } catch (Exception e) { | |
116 | + ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
117 | + e.printStackTrace(new PrintStream(out)); | |
118 | + textAreaShow.setText(out.toString()); | |
119 | + } | |
120 | + }); | |
121 | + } | |
122 | + | |
123 | + { | |
124 | + JMenuItem menuItem = new JMenuItem("別名で保存(A)"); | |
125 | + menuItem.setMnemonic('A'); | |
126 | + menu.add(menuItem); | |
127 | + | |
128 | + menuItem.addActionListener(event -> { | |
129 | + JFileChooser fileChooser = new JFileChooser(); | |
130 | + fileChooser.addChoosableFileFilter(new FileNameExtensionFilter( | |
131 | + "Wulfenite スクリプトファイル(*.wul)", "wul")); | |
132 | + fileChooser.setAcceptAllFileFilterUsed(true); | |
133 | + | |
134 | + int res = fileChooser.showSaveDialog(this); | |
135 | + if (res == JFileChooser.CANCEL_OPTION) { | |
136 | + textAreaShow.setText("ダイアログがキャンセルされました。"); | |
137 | + } else if (res == JFileChooser.ERROR_OPTION) { | |
138 | + textAreaShow.setText("ダイアログ上でエラーが発生しました。"); | |
139 | + } | |
140 | + | |
141 | + try (PrintStream out = new PrintStream( | |
142 | + new FileOutputStream( | |
143 | + fileChooser.getSelectedFile()))) { | |
144 | + out.print(textAreaSource.getText()); | |
145 | + | |
146 | + dirty = false; | |
147 | + handlerFile.x.accept(fileChooser.getSelectedFile()); | |
148 | + updateTitle(); | |
149 | + | |
150 | + } catch (Exception e) { | |
151 | + ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
152 | + e.printStackTrace(new PrintStream(out)); | |
153 | + textAreaShow.setText(out.toString()); | |
154 | + } | |
155 | + }); | |
156 | + } | |
157 | + | |
158 | + { | |
159 | + JMenuItem menuItem = new JMenuItem("上書き保存(S)"); | |
160 | + menuItem.setMnemonic('S'); | |
161 | + menu.add(menuItem); | |
162 | + | |
163 | + menuItem.setEnabled(false); | |
164 | + handlerFile.x = handlerFile.x.andThen(file2 -> { | |
165 | + menuItem.setEnabled(true); | |
166 | + }); | |
167 | + | |
168 | + menuItem.addActionListener(event -> { | |
169 | + try (PrintStream out = new PrintStream( | |
170 | + new FileOutputStream(file))) { | |
171 | + out.print(textAreaSource.getText()); | |
172 | + | |
173 | + dirty = false; | |
174 | + updateTitle(); | |
175 | + | |
176 | + } catch (Exception e) { | |
177 | + ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
178 | + e.printStackTrace(new PrintStream(out)); | |
179 | + textAreaShow.setText(out.toString()); | |
180 | + } | |
181 | + }); | |
182 | + } | |
183 | + | |
184 | + } | |
185 | + | |
186 | + { | |
54 | 187 | JMenu menu = new JMenu("コンパイル(C)"); |
55 | 188 | menu.setMnemonic('C'); |
56 | 189 | menuBar.add(menu); |
@@ -89,18 +222,27 @@ | ||
89 | 222 | @Override |
90 | 223 | public void removeUpdate(DocumentEvent e) |
91 | 224 | { |
225 | + dirty = true; | |
226 | + updateTitle(); | |
227 | + | |
92 | 228 | update(); |
93 | 229 | } |
94 | 230 | |
95 | 231 | @Override |
96 | 232 | public void insertUpdate(DocumentEvent e) |
97 | 233 | { |
234 | + dirty = true; | |
235 | + updateTitle(); | |
236 | + | |
98 | 237 | update(); |
99 | 238 | } |
100 | 239 | |
101 | 240 | @Override |
102 | 241 | public void changedUpdate(DocumentEvent e) |
103 | 242 | { |
243 | + dirty = true; | |
244 | + updateTitle(); | |
245 | + | |
104 | 246 | update(); |
105 | 247 | } |
106 | 248 |
@@ -151,9 +293,11 @@ | ||
151 | 293 | |
152 | 294 | }); |
153 | 295 | threadCompile.setDaemon(true); |
296 | + threadCompile.setName("Compiling"); | |
154 | 297 | threadCompile.start(); |
155 | 298 | |
156 | - setTitle(titleBase + " [コンパイル中]"); | |
299 | + running = true; | |
300 | + updateTitle(); | |
157 | 301 | } |
158 | 302 | |
159 | 303 | protected void compile() throws InterruptedException |
@@ -166,7 +310,8 @@ | ||
166 | 310 | SwingUtilities.invokeLater(() -> { |
167 | 311 | |
168 | 312 | onStopCompile(); |
169 | - setTitle(titleBase); | |
313 | + running = false; | |
314 | + updateTitle(); | |
170 | 315 | |
171 | 316 | // show |
172 | 317 | System.out.println("Syntax Error!!"); |
@@ -185,12 +330,14 @@ | ||
185 | 330 | |
186 | 331 | INode<IWulfeniteScript> node = result.syntax; |
187 | 332 | ArgumentWulfeniteScriptValidate argumentValidate = new ArgumentWulfeniteScriptValidate(result); |
333 | + argumentValidate.stackFrameRoot.getStackFrame().defineVariable("_"); | |
188 | 334 | if (!node.getTag().validate(argumentValidate)) { |
189 | 335 | |
190 | 336 | SwingUtilities.invokeLater(() -> { |
191 | 337 | |
192 | 338 | onStopCompile(); |
193 | - setTitle(titleBase); | |
339 | + running = false; | |
340 | + updateTitle(); | |
194 | 341 | |
195 | 342 | // show |
196 | 343 | System.out.println("Compile Error!!"); |
@@ -210,7 +357,8 @@ | ||
210 | 357 | SwingUtilities.invokeLater(() -> { |
211 | 358 | |
212 | 359 | onStopCompile(); |
213 | - setTitle(titleBase); | |
360 | + running = false; | |
361 | + updateTitle(); | |
214 | 362 | |
215 | 363 | // show |
216 | 364 | textAreaSource.setBackground(new Color(0.8f, 1.0f, 0.8f)); |
@@ -241,7 +389,8 @@ | ||
241 | 389 | if (threadCompile != null) { |
242 | 390 | |
243 | 391 | onStopCompile(); |
244 | - setTitle(titleBase); | |
392 | + running = false; | |
393 | + updateTitle(); | |
245 | 394 | |
246 | 395 | textAreaSource.setBackground(new Color(0.8f, 0.8f, 0.8f)); |
247 | 396 | textAreaShow.setText("コンパイルが中断されました。"); |
@@ -10,6 +10,8 @@ | ||
10 | 10 | import mirrg.event.nitrogen.INitrogenEventRegistry; |
11 | 11 | import mirrg.game.complexcanvas.wulfenite.events.NitrogenEventWulfenite; |
12 | 12 | import mirrg.game.complexcanvas.wulfenite.script.ArgumentWulfeniteScript; |
13 | +import mirrg.game.complexcanvas.wulfenite.script.ArgumentWulfeniteScript.Register; | |
14 | +import mirrg.game.complexcanvas.wulfenite.script.ArgumentWulfeniteScript.Stack; | |
13 | 15 | import mirrg.game.complexcanvas.wulfenite.script.IWulfeniteScript; |
14 | 16 | |
15 | 17 | public class PanelWulfenite extends JPanel |
@@ -35,11 +37,13 @@ | ||
35 | 37 | if (argument == null) return; |
36 | 38 | if (wulfeniteScript == null) return; |
37 | 39 | |
38 | - argument.in = buffer; | |
40 | + // prepare | |
41 | + argument.stack.variables[0] = buffer; | |
42 | + | |
43 | + // invoke | |
39 | 44 | if (!wulfeniteScript.invoke(argument)) { |
40 | 45 | argument.messages.forEach(System.out::println); |
41 | 46 | } |
42 | - buffer.set(argument.out); | |
43 | 47 | } |
44 | 48 | |
45 | 49 | }; |
@@ -64,11 +68,8 @@ | ||
64 | 68 | |
65 | 69 | argument = new ArgumentWulfeniteScript(); |
66 | 70 | argument.validate = event.formula.argumentValidate; |
67 | - argument.out = new StructureComplex(); | |
68 | - argument.bufferRegister = new StructureComplex[ | |
69 | - event.formula.argumentValidate.getLengthBufferRegister()]; | |
70 | - argument.bufferLine = new StructureComplex[ | |
71 | - event.formula.argumentValidate.getLengthBufferLine()]; | |
71 | + argument.stack = new Stack(argument.validate.stackFrameRoot); | |
72 | + argument.register = new Register(argument.validate.registerFrameRoot); | |
72 | 73 | } |
73 | 74 | |
74 | 75 | }); |
@@ -1,36 +1,52 @@ | ||
1 | 1 | package mirrg.game.complexcanvas.wulfenite.script; |
2 | 2 | |
3 | 3 | import java.util.ArrayList; |
4 | -import java.util.Hashtable; | |
5 | 4 | |
6 | 5 | import mirrg.complex.hydrogen.StructureComplex; |
6 | +import mirrg.game.complexcanvas.wulfenite.script.ArgumentWulfeniteScriptValidate.RegisterFrameRoot; | |
7 | +import mirrg.game.complexcanvas.wulfenite.script.ArgumentWulfeniteScriptValidate.StackFrameRoot; | |
7 | 8 | |
8 | 9 | public class ArgumentWulfeniteScript |
9 | 10 | { |
10 | 11 | |
11 | 12 | public ArgumentWulfeniteScriptValidate validate; |
12 | - public StructureComplex in; | |
13 | - public StructureComplex out; | |
14 | 13 | public ArrayList<String> messages = new ArrayList<>(); |
14 | + public Stack stack; | |
15 | + public Register register; | |
15 | 16 | |
16 | 17 | public void addMessage(String message) |
17 | 18 | { |
18 | 19 | messages.add(message); |
19 | 20 | } |
20 | 21 | |
21 | - /** | |
22 | - * 引数バッファ | |
23 | - */ | |
24 | - public StructureComplex[] bufferRegister; | |
22 | + public static class Stack | |
23 | + { | |
25 | 24 | |
26 | - /** | |
27 | - * 行バッファ | |
28 | - */ | |
29 | - public StructureComplex[] bufferLine; | |
25 | + public StructureComplex[] variables; | |
30 | 26 | |
31 | - /** | |
32 | - * 名前付き変数 | |
33 | - */ | |
34 | - public Hashtable<String, StructureComplex> variables = new Hashtable<>(); | |
27 | + public Stack(StackFrameRoot stackFrameRoot) | |
28 | + { | |
29 | + variables = new StructureComplex[stackFrameRoot.maxVariableCount]; | |
30 | + for (int i = 0; i < variables.length; i++) { | |
31 | + variables[i] = new StructureComplex(); | |
32 | + } | |
33 | + } | |
34 | + | |
35 | + } | |
36 | + | |
37 | + public static class Register | |
38 | + { | |
39 | + | |
40 | + public StructureComplex[] registers; | |
41 | + | |
42 | + public Register(RegisterFrameRoot registerFrameRoot) | |
43 | + { | |
44 | + registers = new StructureComplex[registerFrameRoot.maxRegisterCount]; | |
45 | + for (int i = 0; i < registers.length; i++) { | |
46 | + registers[i] = new StructureComplex(); | |
47 | + } | |
48 | + } | |
49 | + | |
50 | + } | |
35 | 51 | |
36 | 52 | } |
@@ -12,14 +12,15 @@ | ||
12 | 12 | public class ArgumentWulfeniteScriptValidate |
13 | 13 | { |
14 | 14 | |
15 | - CompileResult<IWulfeniteScript> result; | |
16 | - private ArrayList<Tuple<INode<?>, String>> messages = new ArrayList<>(); | |
15 | + public final CompileResult<IWulfeniteScript> result; | |
17 | 16 | |
18 | 17 | public ArgumentWulfeniteScriptValidate(CompileResult<IWulfeniteScript> result) |
19 | 18 | { |
20 | 19 | this.result = result; |
21 | 20 | } |
22 | 21 | |
22 | + private ArrayList<Tuple<INode<?>, String>> messages = new ArrayList<>(); | |
23 | + | |
23 | 24 | public void addMessage(INode<?> parent, String message) |
24 | 25 | { |
25 | 26 | messages.add(new Tuple<>(parent, message)); |
@@ -50,34 +51,155 @@ | ||
50 | 51 | .collect(Collectors.joining("\n")); |
51 | 52 | } |
52 | 53 | |
53 | - private int lengthBufferRegister = 0; | |
54 | + public StackFrameRoot stackFrameRoot = new StackFrameRoot(); | |
54 | 55 | |
55 | - private int lengthBufferLine = 0; | |
56 | - | |
57 | - public int getLengthBufferLine() | |
56 | + public static class StackFrameRoot | |
58 | 57 | { |
59 | - return lengthBufferLine; | |
60 | - } | |
61 | 58 | |
62 | - public int getLengthBufferRegister() | |
63 | - { | |
64 | - return lengthBufferRegister; | |
59 | + private StackFrame stackFrame = new StackFrame(this, null); | |
60 | + | |
61 | + public int maxVariableCount = 0; | |
62 | + | |
63 | + public StackFrame getStackFrame() | |
64 | + { | |
65 | + return stackFrame; | |
66 | + } | |
67 | + | |
68 | + public void pushStackFrame() | |
69 | + { | |
70 | + stackFrame = new StackFrame(this, stackFrame); | |
71 | + } | |
72 | + | |
73 | + public void popStackFrame() | |
74 | + { | |
75 | + stackFrame = stackFrame.parent; | |
76 | + } | |
77 | + | |
65 | 78 | } |
66 | 79 | |
67 | - /** | |
68 | - * 引数バッファ | |
69 | - */ | |
70 | - public int allocateBufferRegister() | |
80 | + public static class StackFrame | |
71 | 81 | { |
72 | - return lengthBufferRegister++; | |
82 | + | |
83 | + private StackFrameRoot stackFrameRoot; | |
84 | + public StackFrame parent; | |
85 | + private ArrayList<String> variables = new ArrayList<>(); | |
86 | + | |
87 | + public StackFrame(StackFrameRoot stackFrameRoot, StackFrame parent) | |
88 | + { | |
89 | + this.stackFrameRoot = stackFrameRoot; | |
90 | + this.parent = parent; | |
91 | + } | |
92 | + | |
93 | + /** | |
94 | + * ここまでで全ての利用可能な変数の中に特定の名前が有るかどうか。 | |
95 | + */ | |
96 | + public boolean containsVariable(String name) | |
97 | + { | |
98 | + if (variables.contains(name)) return true; | |
99 | + return parent == null ? false : parent.containsVariable(name); | |
100 | + } | |
101 | + | |
102 | + /** | |
103 | + * このスタックフレームで変数名の占有を宣言。 | |
104 | + * | |
105 | + * @return | |
106 | + * その変数のインデックス。 | |
107 | + * その変数名が利用可能でなかった場合、null。 | |
108 | + */ | |
109 | + public Integer defineVariable(String name) | |
110 | + { | |
111 | + if (containsVariable(name)) return null; | |
112 | + variables.add(name); | |
113 | + | |
114 | + int index = getVariablesCount(); | |
115 | + | |
116 | + if (stackFrameRoot.maxVariableCount < index) { | |
117 | + stackFrameRoot.maxVariableCount = index; | |
118 | + } | |
119 | + | |
120 | + return index - 1; | |
121 | + } | |
122 | + | |
123 | + /** | |
124 | + * ここまでで全ての利用可能な変数の個数。 | |
125 | + */ | |
126 | + public int getVariablesCount() | |
127 | + { | |
128 | + return variables.size() + (parent == null ? 0 : parent.getVariablesCount()); | |
129 | + } | |
130 | + | |
131 | + /** | |
132 | + * ここまでで全ての利用可能な変数のなかで、 | |
133 | + * その変数が宣言された時点で利用可能であった変数の個数。 | |
134 | + */ | |
135 | + public Integer getVariableIndex(String name) | |
136 | + { | |
137 | + int index = variables.indexOf(name); | |
138 | + if (index != -1) { | |
139 | + return index + (parent == null ? 0 : parent.getVariablesCount()); | |
140 | + } | |
141 | + return parent == null ? null : parent.getVariableIndex(name); | |
142 | + } | |
143 | + | |
73 | 144 | } |
74 | 145 | |
75 | - /** | |
76 | - * 行バッファ | |
77 | - */ | |
78 | - public int allocateBufferLine() | |
146 | + public RegisterFrameRoot registerFrameRoot = new RegisterFrameRoot(); | |
147 | + | |
148 | + public static class RegisterFrameRoot | |
79 | 149 | { |
80 | - return lengthBufferLine++; | |
150 | + | |
151 | + private RegisterFrame registerFrame = new RegisterFrame(this, null); | |
152 | + | |
153 | + public int maxRegisterCount = 0; | |
154 | + | |
155 | + public RegisterFrame getRegisterFrame() | |
156 | + { | |
157 | + return registerFrame; | |
158 | + } | |
159 | + | |
160 | + public void pushRegisterFrame() | |
161 | + { | |
162 | + registerFrame = new RegisterFrame(this, registerFrame); | |
163 | + } | |
164 | + | |
165 | + public void popRegisterFrame() | |
166 | + { | |
167 | + registerFrame = registerFrame.parent; | |
168 | + } | |
169 | + | |
170 | + } | |
171 | + | |
172 | + public static class RegisterFrame | |
173 | + { | |
174 | + | |
175 | + private RegisterFrameRoot registerFrameRoot; | |
176 | + public RegisterFrame parent; | |
177 | + private int registerCount; | |
178 | + | |
179 | + public RegisterFrame(RegisterFrameRoot registerFrameRoot, RegisterFrame parent) | |
180 | + { | |
181 | + this.registerFrameRoot = registerFrameRoot; | |
182 | + this.parent = parent; | |
183 | + } | |
184 | + | |
185 | + public int defineRegister() | |
186 | + { | |
187 | + registerCount++; | |
188 | + | |
189 | + int index = getRegisterCount(); | |
190 | + | |
191 | + if (registerFrameRoot.maxRegisterCount < index) { | |
192 | + registerFrameRoot.maxRegisterCount = index; | |
193 | + } | |
194 | + | |
195 | + return index - 1; | |
196 | + } | |
197 | + | |
198 | + public int getRegisterCount() | |
199 | + { | |
200 | + return registerCount + (parent == null ? 0 : parent.getRegisterCount()); | |
201 | + } | |
202 | + | |
81 | 203 | } |
82 | 204 | |
83 | 205 | } |
@@ -1,27 +1,37 @@ | ||
1 | 1 | package mirrg.game.complexcanvas.wulfenite.script; |
2 | 2 | |
3 | 3 | import static mirrg.compile.iodine.util.HStatements.*; |
4 | - | |
5 | -import java.util.ArrayList; | |
6 | -import java.util.function.BiPredicate; | |
7 | - | |
8 | 4 | import mirrg.compile.iodine.CompileManager; |
9 | 5 | import mirrg.compile.iodine.INode; |
10 | 6 | import mirrg.compile.iodine.IStatement; |
11 | 7 | import mirrg.compile.iodine.comment.CommentManager; |
12 | 8 | import mirrg.compile.iodine.statements.StatementRoot; |
13 | -import mirrg.compile.iodine.statements.connection.ITagParent; | |
14 | 9 | import mirrg.compile.iodine.statements.wrapper.StatementSupplier; |
15 | 10 | import mirrg.compile.iodine.util.HStatements; |
16 | -import mirrg.compile.iodine.util.ITagOperator; | |
17 | -import mirrg.complex.hydrogen.StructureComplex; | |
18 | -import mirrg.complex.hydrogen.functions.Exponential; | |
19 | -import mirrg.complex.hydrogen.functions.Trigonometry; | |
20 | -import mirrg.game.complexcanvas.wulfenite.script.TagsCommented.TagComments; | |
21 | -import mirrg.game.complexcanvas.wulfenite.script.TagsCommented.TagPattern; | |
22 | -import mirrg.game.complexcanvas.wulfenite.script.TagsCommented.TagPatternImpl; | |
23 | -import mirrg.game.complexcanvas.wulfenite.script.TagsCommented.TagToken; | |
24 | -import mirrg.game.complexcanvas.wulfenite.script.TagsCommented.TagTokenImpl; | |
11 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.ITagExpression; | |
12 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagDo; | |
13 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagFunction; | |
14 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagFunction.TagArgumentList; | |
15 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagIif; | |
16 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagNegation; | |
17 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagNumber; | |
18 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagOperator; | |
19 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagOperatorLeft; | |
20 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagOperatorRight; | |
21 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.TagVariable; | |
22 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.ITagRunnable; | |
23 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.TagAssignment; | |
24 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.TagBlock; | |
25 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.TagDefineVariable; | |
26 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.TagEmptyStatement; | |
27 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.TagFor; | |
28 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.TagStackFrame; | |
29 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.TagWhile; | |
30 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.TagComments; | |
31 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.TagPattern; | |
32 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.TagPatternImpl; | |
33 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.TagToken; | |
34 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.TagTokenImpl; | |
25 | 35 | |
26 | 36 | public class CompilerWulfeniteScript |
27 | 37 | { |
@@ -35,12 +45,6 @@ | ||
35 | 45 | .or(pattern(TagPatternImpl::new, "[ \\t\\r\\n]+", "CommentSpaces")) |
36 | 46 | .or(pattern(TagPatternImpl::new, "//.*?(?=[\\r\\n]|\\Z)", "CommentLine"))))); |
37 | 47 | |
38 | - // 全ての式 | |
39 | - StatementSupplier<ITagExpression> statementExpression = | |
40 | - new StatementSupplier<>(); | |
41 | - | |
42 | - // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | |
43 | - | |
44 | 48 | // 識別子トークン |
45 | 49 | IStatement<TagPattern> statementIdentifier = |
46 | 50 | pattern2("[a-zA-Z_][a-zA-Z0-9_]*", "Identifier"); |
@@ -49,114 +53,292 @@ | ||
49 | 53 | IStatement<TagPattern> statementTokenNumber = |
50 | 54 | pattern2("([+\\-]?\\d+)(?:\\.(\\d+))?(?:[eE]([+\\-]?\\d+))?([iI])?", "Number"); |
51 | 55 | |
52 | - // 変数 | |
53 | - IStatement<ITagExpression> statementVariable = | |
54 | - wrap(map(statementIdentifier, | |
55 | - tag -> new TagVariable(tag))); | |
56 | - | |
57 | - // 数値リテラル | |
58 | - IStatement<ITagExpression> statementNumber = | |
59 | - wrap(map(statementTokenNumber, | |
60 | - tag -> new TagNumber(tag))); | |
61 | - | |
62 | - // カッコ | |
63 | - IStatement<ITagExpression> statementBracket = | |
64 | - wrap(serial(TagBracket::new) | |
65 | - .and(token2("(", false), | |
66 | - (built, node) -> {}) | |
67 | - .and(statementExpression, | |
68 | - (built, node) -> built.getTag().node = node) | |
69 | - .and(token2(")", false), | |
70 | - (built, node) -> {})); | |
56 | + // 全ての式 | |
57 | + StatementSupplier<ITagExpression> statementExpression = | |
58 | + new StatementSupplier<>(); | |
71 | 59 | |
72 | - // 関数 | |
73 | - IStatement<ITagExpression> statementFunction = | |
74 | - wrap(filter(serial(TagFunction::new) | |
75 | - .and(statementIdentifier, | |
76 | - (built, node) -> built.getTag().nodeMethod = node) | |
77 | - .and(HStatements.<TagArguments> or() | |
78 | - .or(voidStatement(TagArguments::new)) | |
79 | - .or(serial(TagArguments::new) | |
80 | - .and(token2("(", false), | |
81 | - (built, node) -> {}) | |
82 | - .and(operator(TagArgumentList::new, | |
83 | - statementExpression, | |
84 | - token2(",", false)), | |
85 | - (built, node) -> built.getTag().nodes = node) | |
86 | - .and(token2(")", false), | |
87 | - (built, node) -> {})) | |
88 | - .or(serial(TagArguments::new) | |
89 | - .and(token2("(", false), | |
90 | - (built, node) -> {}) | |
91 | - .and(token2(")", false), | |
92 | - (built, node) -> {})), | |
93 | - (built, node) -> built.getTag().nodeArguments = node), | |
94 | - node -> { | |
95 | - node.getTag().parent = node; | |
96 | - return true; | |
97 | - })); | |
60 | + // 全ての実行可能命令 | |
61 | + StatementSupplier<ITagRunnable> statementLine = | |
62 | + new StatementSupplier<>(); | |
98 | 63 | |
99 | - // 式の最小構成 | |
100 | - IStatement<ITagExpression> statementLiteral = | |
101 | - wrap(HStatements.<ITagExpression> or() | |
102 | - .or(statementVariable) | |
103 | - .or(statementNumber) | |
104 | - .or(statementBracket) | |
105 | - .or(statementFunction)); | |
106 | - | |
107 | - // べき乗 | |
108 | - IStatement<ITagExpression> statementPower = | |
109 | - wrap(operator(TagOperatorRight::new, statementLiteral, pattern2("[\\^]", "OperatorPower"))); | |
110 | - | |
111 | - // 乗算 | |
112 | - IStatement<ITagExpression> statementMultiplication = | |
113 | - wrap(operator(TagOperatorLeft::new, statementPower, pattern2("[*/]", "OperatorMultiplication"))); | |
64 | + // 全ての実行可能命令列 | |
65 | + StatementSupplier<ITagRunnable> statementLines = | |
66 | + new StatementSupplier<>(); | |
114 | 67 | |
115 | - // 加算 | |
116 | - IStatement<ITagExpression> statementAddition = | |
117 | - wrap(operator(TagOperatorLeft::new, statementMultiplication, pattern2("[+\\-]", "OperatorAddition"))); | |
118 | - | |
119 | - // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | |
68 | + { // ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ | |
120 | 69 | |
121 | - // 全ての式 | |
122 | - statementExpression.set(statementAddition); | |
70 | + // 変数 | |
71 | + IStatement<ITagExpression> statementVariable = | |
72 | + wrap(serial(TagVariable::new) | |
73 | + .and(statementIdentifier, | |
74 | + (built, node) -> built.getTag().node = node)); | |
123 | 75 | |
124 | - // 代入 | |
125 | - IStatement<IWulfeniteScript> statementAssignment = | |
126 | - wrap(HStatements.<TagAssignment> or() | |
127 | - .or(serial(TagAssignmentVariable::new) | |
128 | - .and(statementIdentifier, | |
129 | - (built, node) -> built.getTag().variable = node) | |
130 | - .and(token2("=", false), | |
76 | + // 数値リテラル | |
77 | + IStatement<ITagExpression> statementNumber = | |
78 | + wrap(map(statementTokenNumber, | |
79 | + tag -> new TagNumber(tag))); | |
80 | + | |
81 | + // カッコ | |
82 | + IStatement<ITagExpression> statementBracket = | |
83 | + wrap(map(HStatements.<TagWrapper<ITagExpression>> serial(TagWrapper::new) | |
84 | + .and(token2("(", false), | |
131 | 85 | (built, node) -> {}) |
132 | 86 | .and(statementExpression, |
133 | 87 | (built, node) -> built.getTag().node = node) |
134 | - .and(token2(";", false), | |
135 | - (built, node) -> {})) | |
136 | - .or(serial(TagAssignmentLine::new) | |
88 | + .and(token2(")", false), | |
89 | + (built, node) -> {}), | |
90 | + tag -> tag.node.getTag())); | |
91 | + | |
92 | + // do | |
93 | + IStatement<ITagExpression> statementDo = | |
94 | + wrap(serial(TagDo::new) | |
95 | + .and(token2("do", true), | |
96 | + (built, node) -> {}) | |
97 | + .and(token2("{", false), | |
98 | + (built, node) -> {}) | |
99 | + .and(statementLines, | |
100 | + (built, node) -> built.getTag().nodeRunnable = node) | |
137 | 101 | .and(statementExpression, |
138 | - (built, node) -> built.getTag().node = node) | |
102 | + (built, node) -> built.getTag().nodeLast = node) | |
103 | + .and(token2("}", false), | |
104 | + (built, node) -> {})); | |
105 | + | |
106 | + // 関数 | |
107 | + IStatement<ITagExpression> statementFunction = | |
108 | + wrap(serial(TagFunction::new) | |
109 | + .and(statementIdentifier, | |
110 | + (built, node) -> built.getTag().nodeMethod = node) | |
111 | + .and(HStatements.<TagArgumentList> or() | |
112 | + .or(map(HStatements.<TagWrapper<TagArgumentList>> serial(TagWrapper::new) | |
113 | + .and(token2("(", false), | |
114 | + (built, node) -> {}) | |
115 | + .and(operator(TagArgumentList::new, | |
116 | + statementExpression, | |
117 | + token2(",", false)), | |
118 | + (built, node) -> built.getTag().node = node) | |
119 | + .and(token2(")", false), | |
120 | + (built, node) -> {}), | |
121 | + tag -> tag.node.getTag())) | |
122 | + .or(serial(TagArgumentList::new) | |
123 | + .and(token2("(", false), | |
124 | + (built, node) -> {}) | |
125 | + .and(token2(")", false), | |
126 | + (built, node) -> {})), | |
127 | + (built, node) -> built.getTag().nodeArguments = node)); | |
128 | + | |
129 | + // 式の最小構成 | |
130 | + IStatement<ITagExpression> statementLiteral = | |
131 | + wrap(HStatements.<ITagExpression> or() | |
132 | + .or(statementVariable) | |
133 | + .or(statementNumber) | |
134 | + .or(statementBracket) | |
135 | + .or(statementFunction) | |
136 | + .or(statementDo)); | |
137 | + | |
138 | + // べき乗 | |
139 | + IStatement<ITagExpression> statementPower = | |
140 | + operatorOptimization(operator(TagOperatorRight::new, statementLiteral, | |
141 | + wrap(pattern2("[\\^]", "OperatorPower")))); | |
142 | + | |
143 | + // 負 | |
144 | + IStatement<ITagExpression> statementNgationNumeric = | |
145 | + wrap(HStatements.<ITagExpression> or() | |
146 | + .or(statementPower) | |
147 | + .or(serial(TagNegation::new) | |
148 | + .and(token2("-", false), | |
149 | + (built, node) -> built.getTag().isBoolean = false) | |
150 | + .and(statementPower, | |
151 | + (built, node) -> built.getTag().node = node))); | |
152 | + | |
153 | + // 乗算 | |
154 | + IStatement<ITagExpression> statementMultiplication = | |
155 | + operatorOptimization(operator(TagOperatorLeft::new, statementNgationNumeric, | |
156 | + wrap(pattern2("[*/]", "OperatorMultiplication")))); | |
157 | + | |
158 | + // 加算 | |
159 | + IStatement<ITagExpression> statementAddition = | |
160 | + operatorOptimization(operator(TagOperatorLeft::new, statementMultiplication, | |
161 | + wrap(pattern2("[+\\-]", "OperatorAddition")))); | |
162 | + | |
163 | + // 比較 | |
164 | + IStatement<ITagExpression> statementCompare = | |
165 | + operatorOptimization(operator(TagOperatorLeft::new, statementAddition, | |
166 | + wrap(pattern2("(?:[<>]=?|[=!]=)", "OperatorCompare")))); | |
167 | + | |
168 | + // 否定 | |
169 | + IStatement<ITagExpression> statementNgation = | |
170 | + wrap(HStatements.<ITagExpression> or() | |
171 | + .or(statementCompare) | |
172 | + .or(serial(TagNegation::new) | |
173 | + .and(token2("!", false), | |
174 | + (built, node) -> built.getTag().isBoolean = true) | |
175 | + .and(statementCompare, | |
176 | + (built, node) -> built.getTag().node = node))); | |
177 | + | |
178 | + // 論理積 | |
179 | + IStatement<ITagExpression> statementAnd = | |
180 | + operatorOptimization(operator(TagOperatorLeft::new, statementNgation, | |
181 | + wrap(token2("&&", false)))); | |
182 | + | |
183 | + // 論理和 | |
184 | + IStatement<ITagExpression> statementOr = | |
185 | + operatorOptimization(operator(TagOperatorLeft::new, statementAnd, | |
186 | + wrap(token2("||", false)))); | |
187 | + | |
188 | + // 選択 | |
189 | + IStatement<ITagExpression> statementIif = | |
190 | + wrap(HStatements.<ITagExpression> or() | |
191 | + .or(statementOr) | |
192 | + .or(serial(TagIif::new) | |
193 | + .and(statementOr, | |
194 | + (built, node) -> built.getTag().nodeCondition = node) | |
195 | + .and(token2("?", false), | |
196 | + (built, node) -> {}) | |
197 | + .and(statementOr, | |
198 | + (built, node) -> built.getTag().nodeTrue = node) | |
199 | + .and(token2(":", false), | |
200 | + (built, node) -> {}) | |
201 | + .and(statementOr, | |
202 | + (built, node) -> built.getTag().nodeFalse = node))); | |
203 | + | |
204 | + statementExpression.set(statementIif); | |
205 | + | |
206 | + } // ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲ | |
207 | + | |
208 | + { // ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ | |
209 | + | |
210 | + // 空行 | |
211 | + IStatement<ITagRunnable> statementEmptyStatement = | |
212 | + wrap(map(token2(";", false), TagEmptyStatement::new)); | |
213 | + | |
214 | + // 代入式 | |
215 | + IStatement<TagAssignment> statementAssignmentImpl = | |
216 | + HStatements.<TagAssignment> or() | |
217 | + .or(serial(TagAssignment::new) | |
218 | + .and(statementIdentifier, | |
219 | + (built, node) -> built.getTag().nodeVariable = node) | |
220 | + .and(token2("=", false), | |
221 | + (built, node) -> {}) | |
222 | + .and(statementExpression, | |
223 | + (built, node) -> built.getTag().node = node)) | |
224 | + .or(serial(TagAssignment::new) | |
225 | + .and(statementExpression, | |
226 | + (built, node) -> built.getTag().node = node)); | |
227 | + | |
228 | + // 代入 | |
229 | + IStatement<ITagRunnable> statementAssignment = | |
230 | + wrap(map(HStatements.<TagWrapper<ITagRunnable>> serial(TagWrapper::new) | |
231 | + .and(statementAssignmentImpl, | |
232 | + (built, node) -> built.getTag().node = INode.cast(node)) | |
139 | 233 | .and(token2(";", false), |
140 | - (built, node) -> {}))); | |
234 | + (built, node) -> {}), | |
235 | + tag -> tag.node.getTag())); | |
141 | 236 | |
142 | - // 命令行 | |
143 | - IStatement<IWulfeniteScript> statementStatement = | |
144 | - statementAssignment; | |
237 | + // ブロック | |
238 | + IStatement<ITagRunnable> statementBlock = | |
239 | + wrap(serial(TagStackFrame::new) | |
240 | + .and(token2("{", false), | |
241 | + (built, node) -> {}) | |
242 | + .and(statementLines, | |
243 | + (built, node) -> built.getTag().node = node) | |
244 | + .and(token2("}", false), | |
245 | + (built, node) -> {})); | |
145 | 246 | |
146 | - IStatement<IWulfeniteScript> statementRunnable = | |
147 | - wrap(loop(TagRunnable::new, statementStatement)); | |
247 | + // 変数宣言 | |
248 | + IStatement<ITagRunnable> statementDefineVariable = | |
249 | + wrap(HStatements.<ITagRunnable> or() | |
250 | + .or(serial(TagDefineVariable::new) | |
251 | + .and(token2("var", true), | |
252 | + (built, node) -> {}) | |
253 | + .and(statementIdentifier, | |
254 | + (built, node) -> built.getTag().nodeVariable = node) | |
255 | + .and(token2("=", false), | |
256 | + (built, node) -> {}) | |
257 | + .and(statementExpression, | |
258 | + (built, node) -> built.getTag().node = node) | |
259 | + .and(token2(";", false), | |
260 | + (built, node) -> {})) | |
261 | + .or(serial(TagDefineVariable::new) | |
262 | + .and(token2("var", true), | |
263 | + (built, node) -> {}) | |
264 | + .and(statementIdentifier, | |
265 | + (built, node) -> built.getTag().nodeVariable = node) | |
266 | + .and(token2(";", false), | |
267 | + (built, node) -> {}))); | |
268 | + | |
269 | + // while | |
270 | + IStatement<ITagRunnable> statementWhile = | |
271 | + wrap(serial(TagWhile::new) | |
272 | + .and(token2("while", true), | |
273 | + (built, node) -> {}) | |
274 | + .and(token2("(", false), | |
275 | + (built, node) -> {}) | |
276 | + .and(statementExpression, | |
277 | + (built, node) -> built.getTag().nodeCondition = node) | |
278 | + .and(token2(")", false), | |
279 | + (built, node) -> {}) | |
280 | + .and(statementLine, | |
281 | + (built, node) -> built.getTag().nodeRunnable = node)); | |
282 | + | |
283 | + // while | |
284 | + IStatement<ITagRunnable> statementFor = | |
285 | + wrap(serial(TagFor::new) | |
286 | + .and(token2("for", true), | |
287 | + (built, node) -> {}) | |
288 | + .and(token2("(", false), | |
289 | + (built, node) -> {}) | |
290 | + .and(statementLine, | |
291 | + (built, node) -> built.getTag().nodeInitialize = node) | |
292 | + .and(statementExpression, | |
293 | + (built, node) -> built.getTag().nodeCondition = node) | |
294 | + .and(token2(";", false), | |
295 | + (built, node) -> {}) | |
296 | + .and(statementAssignmentImpl, | |
297 | + (built, node) -> built.getTag().nodeIncrement = INode.cast(node)) | |
298 | + .and(token2(")", false), | |
299 | + (built, node) -> {}) | |
300 | + .and(statementLine, | |
301 | + (built, node) -> built.getTag().nodeRunnable = node)); | |
302 | + | |
303 | + // 命令行 | |
304 | + IStatement<ITagRunnable> statementStatement = | |
305 | + HStatements.<ITagRunnable> or() | |
306 | + .or(statementEmptyStatement) | |
307 | + .or(statementAssignment) | |
308 | + .or(statementBlock) | |
309 | + .or(statementDefineVariable) | |
310 | + .or(statementWhile) | |
311 | + .or(statementFor); | |
312 | + | |
313 | + // 命令行列 | |
314 | + IStatement<ITagRunnable> statementStatements = | |
315 | + wrap(loop(TagBlock::new, statementStatement)); | |
316 | + | |
317 | + statementLine.set(statementStatement); | |
318 | + statementLines.set(statementStatements); | |
319 | + | |
320 | + } // ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲ | |
148 | 321 | |
149 | 322 | // ソースコード全体(ファイル末コメントのため) |
150 | 323 | IStatement<IWulfeniteScript> statementSource = |
151 | - wrap(serial(TagWrapper::new) | |
152 | - .and(statementRunnable, | |
324 | + wrap(map(HStatements.<TagWrapper<ITagRunnable>> serial(TagWrapper::new) | |
325 | + .and(statementLines, | |
153 | 326 | (built, node) -> built.getTag().node = node) |
154 | 327 | .and(pattern2("\\Z", "EndOfSource"), |
155 | - (built, node) -> {})); | |
328 | + (built, node) -> {}), | |
329 | + tag -> tag.node.getTag())); | |
156 | 330 | |
157 | 331 | compileManager = new CompileManager<>(new StatementRoot<>(statementSource)); |
158 | 332 | } |
159 | 333 | |
334 | + private IStatement<ITagExpression> operatorOptimization(IStatement<TagOperator> operator) | |
335 | + { | |
336 | + return wrap(map(operator, | |
337 | + tag -> tag.nodeExpressions.size() == 1 | |
338 | + ? tag.nodeExpressions.get(0).getTag() | |
339 | + : tag)); | |
340 | + } | |
341 | + | |
160 | 342 | private final CompileManager<IWulfeniteScript> compileManager; |
161 | 343 | |
162 | 344 | public CompileManager<IWulfeniteScript> getCompileManager() |
@@ -166,566 +348,10 @@ | ||
166 | 348 | |
167 | 349 | private CommentManager<TagComments> commentManager; |
168 | 350 | |
169 | - public static interface ITagExpression | |
170 | - { | |
171 | - | |
172 | - public boolean validate(ArgumentWulfeniteScriptValidate argument); | |
173 | - | |
174 | - public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out); | |
175 | - | |
176 | - } | |
177 | - | |
178 | - public static interface ITagChild | |
179 | - { | |
180 | - | |
181 | - public void setParent(INode<?> parent); | |
182 | - | |
183 | - } | |
184 | - | |
185 | - public static class TagFunction implements ITagExpression, ITagChild | |
186 | - { | |
187 | - | |
188 | - public INode<?> parent; | |
189 | - public INode<TagPattern> nodeMethod; | |
190 | - public INode<TagArguments> nodeArguments; | |
191 | - public BiPredicate<ArgumentWulfeniteScript, StructureComplex> method; | |
192 | - | |
193 | - @Override | |
194 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
195 | - { | |
196 | - if (nodeArguments.getTag().nodes == null) { | |
197 | - argument.addMessage(parent, "引数の数が不正です: " + 0); | |
198 | - return false; | |
199 | - } | |
200 | - | |
201 | - if (nodeArguments.getTag().nodes.getTag().nodes.size() != 1) { | |
202 | - argument.addMessage(parent, "引数の数が不正です: " + nodeArguments.getTag().nodes.getTag().nodes.size()); | |
203 | - return false; | |
204 | - } | |
205 | - INode<ITagExpression> nodeArgument = nodeArguments.getTag().nodes.getTag().nodes.get(0); | |
206 | - | |
207 | - if (!nodeArgument.getTag().validate(argument)) return false; | |
208 | - | |
209 | - String string = nodeMethod.getTag().child.getTag().string; | |
210 | - | |
211 | - if (string.equals("pow")) { | |
212 | - method = (argument2, out) -> { | |
213 | - nodeArgument.getTag().calculate(argument2, out); | |
214 | - Exponential.pow(out, 2); | |
215 | - return true; | |
216 | - }; | |
217 | - } else if (string.equals("exp")) { | |
218 | - method = (argument2, out) -> { | |
219 | - nodeArgument.getTag().calculate(argument2, out); | |
220 | - Exponential.exp(out); | |
221 | - return true; | |
222 | - }; | |
223 | - } else if (string.equals("log")) { | |
224 | - method = (argument2, out) -> { | |
225 | - nodeArgument.getTag().calculate(argument2, out); | |
226 | - Exponential.log(out); | |
227 | - return true; | |
228 | - }; | |
229 | - } else if (string.equals("sin")) { | |
230 | - method = (argument2, out) -> { | |
231 | - nodeArgument.getTag().calculate(argument2, out); | |
232 | - Trigonometry.sin(out); | |
233 | - return true; | |
234 | - }; | |
235 | - } else if (string.equals("cos")) { | |
236 | - method = (argument2, out) -> { | |
237 | - nodeArgument.getTag().calculate(argument2, out); | |
238 | - Trigonometry.cos(out); | |
239 | - return true; | |
240 | - }; | |
241 | - } else if (string.equals("tan")) { | |
242 | - method = (argument2, out) -> { | |
243 | - nodeArgument.getTag().calculate(argument2, out); | |
244 | - Trigonometry.tan(out); | |
245 | - return true; | |
246 | - }; | |
247 | - } else if (string.equals("sinh")) { | |
248 | - method = (argument2, out) -> { | |
249 | - nodeArgument.getTag().calculate(argument2, out); | |
250 | - Trigonometry.sinh(out); | |
251 | - return true; | |
252 | - }; | |
253 | - } else if (string.equals("cosh")) { | |
254 | - method = (argument2, out) -> { | |
255 | - nodeArgument.getTag().calculate(argument2, out); | |
256 | - Trigonometry.cosh(out); | |
257 | - return true; | |
258 | - }; | |
259 | - } else if (string.equals("tanh")) { | |
260 | - method = (argument2, out) -> { | |
261 | - nodeArgument.getTag().calculate(argument2, out); | |
262 | - Trigonometry.tanh(out); | |
263 | - return true; | |
264 | - }; | |
265 | - } else if (string.equals("inv")) { | |
266 | - method = (argument2, out) -> { | |
267 | - nodeArgument.getTag().calculate(argument2, out); | |
268 | - out.inv(); | |
269 | - return true; | |
270 | - }; | |
271 | - } else if (string.equals("neg")) { | |
272 | - method = (argument2, out) -> { | |
273 | - nodeArgument.getTag().calculate(argument2, out); | |
274 | - out.neg(); | |
275 | - return true; | |
276 | - }; | |
277 | - } else if (string.equals("con")) { | |
278 | - method = (argument2, out) -> { | |
279 | - nodeArgument.getTag().calculate(argument2, out); | |
280 | - out.con(); | |
281 | - return true; | |
282 | - }; | |
283 | - } else if (string.equals("abs")) { | |
284 | - method = (argument2, out) -> { | |
285 | - nodeArgument.getTag().calculate(argument2, out); | |
286 | - argument2.in.set(out); | |
287 | - out.re = argument2.in.getAbstract(); | |
288 | - out.im = 0; | |
289 | - return true; | |
290 | - }; | |
291 | - } else if (string.equals("arg")) { | |
292 | - method = (argument2, out) -> { | |
293 | - nodeArgument.getTag().calculate(argument2, out); | |
294 | - argument2.in.set(out); | |
295 | - out.re = argument2.in.getArgument(); | |
296 | - out.im = 0; | |
297 | - return true; | |
298 | - }; | |
299 | - } else if (string.equals("re")) { | |
300 | - method = (argument2, out) -> { | |
301 | - nodeArgument.getTag().calculate(argument2, out); | |
302 | - argument2.in.set(out); | |
303 | - out.re = argument2.in.re; | |
304 | - out.im = 0; | |
305 | - return true; | |
306 | - }; | |
307 | - } else if (string.equals("im")) { | |
308 | - method = (argument2, out) -> { | |
309 | - nodeArgument.getTag().calculate(argument2, out); | |
310 | - argument2.in.set(out); | |
311 | - out.re = argument2.in.im; | |
312 | - out.im = 0; | |
313 | - return true; | |
314 | - }; | |
315 | - } else { | |
316 | - argument.addMessage(parent, "不明な関数です: " + string); | |
317 | - return false; | |
318 | - } | |
319 | - | |
320 | - return true; | |
321 | - } | |
322 | - | |
323 | - @Override | |
324 | - public void setParent(INode<?> parent) | |
325 | - { | |
326 | - this.parent = parent; | |
327 | - } | |
328 | - | |
329 | - @Override | |
330 | - public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
331 | - { | |
332 | - return method.test(argument, out); | |
333 | - } | |
334 | - | |
335 | - } | |
336 | - | |
337 | - public static class TagRunnable implements IWulfeniteScript, ITagParent<IWulfeniteScript> | |
338 | - { | |
339 | - | |
340 | - public ArrayList<INode<IWulfeniteScript>> nodes = new ArrayList<>(); | |
341 | - public IWulfeniteScript[] tags; | |
342 | - | |
343 | - @Override | |
344 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
345 | - { | |
346 | - boolean flag = true; | |
347 | - | |
348 | - tags = new IWulfeniteScript[nodes.size()]; | |
349 | - for (int i = 0; i < nodes.size(); i++) { | |
350 | - tags[i] = nodes.get(i).getTag(); | |
351 | - | |
352 | - if (!tags[i].validate(argument)) flag = false; | |
353 | - } | |
354 | - | |
355 | - return flag; | |
356 | - } | |
357 | - | |
358 | - @Override | |
359 | - public boolean invoke(ArgumentWulfeniteScript argument) | |
360 | - { | |
361 | - for (IWulfeniteScript tag : tags) { | |
362 | - if (!tag.invoke(argument)) return false; | |
363 | - argument.in.set(argument.out); | |
364 | - } | |
365 | - return true; | |
366 | - } | |
367 | - | |
368 | - @Override | |
369 | - public void set(int index, INode<IWulfeniteScript> node) | |
370 | - { | |
371 | - while (index >= nodes.size()) { | |
372 | - nodes.add(null); | |
373 | - } | |
374 | - nodes.set(index, node); | |
375 | - } | |
376 | - | |
377 | - } | |
378 | - | |
379 | - public static abstract class TagAssignment implements IWulfeniteScript | |
380 | - { | |
381 | - | |
382 | - public INode<ITagExpression> node; | |
383 | - | |
384 | - @Override | |
385 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
386 | - { | |
387 | - return node.getTag().validate(argument); | |
388 | - } | |
389 | - | |
390 | - } | |
391 | - | |
392 | - public static class TagAssignmentVariable extends TagAssignment | |
393 | - { | |
394 | - | |
395 | - public INode<TagPattern> variable; | |
396 | - | |
397 | - @Override | |
398 | - public boolean invoke(ArgumentWulfeniteScript argument) | |
399 | - { | |
400 | - String nameVariable = variable.getTag().child.getTag().string; | |
401 | - | |
402 | - if (nameVariable.equals("_")) { | |
403 | - StructureComplex out = argument.out; | |
404 | - if (!node.getTag().calculate(argument, out)) return false; | |
405 | - } else { | |
406 | - StructureComplex out = new StructureComplex(); | |
407 | - node.getTag().calculate(argument, out); | |
408 | - argument.variables.put(nameVariable, out); | |
409 | - | |
410 | - argument.out.set(argument.in); | |
411 | - } | |
412 | - | |
413 | - return true; | |
414 | - } | |
415 | - | |
416 | - } | |
417 | - | |
418 | - public static class TagAssignmentLine extends TagAssignment | |
419 | - { | |
420 | - | |
421 | - public int indexLine; | |
422 | - | |
423 | - @Override | |
424 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
425 | - { | |
426 | - indexLine = argument.allocateBufferLine(); | |
427 | - return super.validate(argument); | |
428 | - } | |
429 | - | |
430 | - @Override | |
431 | - public boolean invoke(ArgumentWulfeniteScript argument) | |
432 | - { | |
433 | - argument.bufferLine[indexLine] = new StructureComplex(); | |
434 | - return node.getTag().calculate(argument, argument.bufferLine[indexLine]); | |
435 | - } | |
436 | - | |
437 | - } | |
438 | - | |
439 | - public static class TagWrapper implements IWulfeniteScript | |
351 | + public static class TagWrapper<T> | |
440 | 352 | { |
441 | 353 | |
442 | - public INode<? extends IWulfeniteScript> node; | |
443 | - public IWulfeniteScript tag; | |
444 | - | |
445 | - @Override | |
446 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
447 | - { | |
448 | - tag = node.getTag(); | |
449 | - if (!tag.validate(argument)) return false; | |
450 | - return true; | |
451 | - } | |
452 | - | |
453 | - @Override | |
454 | - public boolean invoke(ArgumentWulfeniteScript argument) | |
455 | - { | |
456 | - return tag.invoke(argument); | |
457 | - } | |
458 | - | |
459 | - } | |
460 | - | |
461 | - public static class TagVariable implements ITagExpression | |
462 | - { | |
463 | - | |
464 | - public TagPattern pattern; | |
465 | - | |
466 | - public TagVariable(TagPattern pattern) | |
467 | - { | |
468 | - this.pattern = pattern; | |
469 | - } | |
470 | - | |
471 | - @Override | |
472 | - public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
473 | - { | |
474 | - String nameVariable = pattern.child.getTag().string; | |
475 | - if (nameVariable.equals("_")) { | |
476 | - out.set(argument.in); | |
477 | - } else { | |
478 | - StructureComplex in = argument.variables.get(nameVariable); | |
479 | - if (in == null) { | |
480 | - out.set(0, 0); | |
481 | - } else { | |
482 | - out.set(in); | |
483 | - } | |
484 | - } | |
485 | - return true; | |
486 | - } | |
487 | - | |
488 | - @Override | |
489 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
490 | - { | |
491 | - return true; | |
492 | - } | |
493 | - | |
494 | - } | |
495 | - | |
496 | - public static class TagNumber implements ITagExpression | |
497 | - { | |
498 | - | |
499 | - public TagPattern pattern; | |
500 | - public StructureComplex value; | |
501 | - | |
502 | - public TagNumber(TagPattern pattern) | |
503 | - { | |
504 | - this.pattern = pattern; | |
505 | - } | |
506 | - | |
507 | - @Override | |
508 | - public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
509 | - { | |
510 | - out.set(value); | |
511 | - return true; | |
512 | - } | |
513 | - | |
514 | - @Override | |
515 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
516 | - { | |
517 | - String a = pattern.child.getTag().matcher.group(1); | |
518 | - String b = pattern.child.getTag().matcher.group(2); | |
519 | - String c = pattern.child.getTag().matcher.group(3); | |
520 | - String d = pattern.child.getTag().matcher.group(4); | |
521 | - | |
522 | - StringBuilder sb = new StringBuilder(); | |
523 | - sb.append(a); | |
524 | - if (b != null) { | |
525 | - sb.append("."); | |
526 | - sb.append(b); | |
527 | - } | |
528 | - if (c != null) { | |
529 | - sb.append("E"); | |
530 | - sb.append(c); | |
531 | - } | |
532 | - double value2 = Double.parseDouble(sb.toString()); | |
533 | - | |
534 | - value = new StructureComplex(); | |
535 | - if (d != null) { | |
536 | - value.set(0, value2); | |
537 | - } else { | |
538 | - value.set(value2, 0); | |
539 | - } | |
540 | - | |
541 | - System.out.println("" | |
542 | - + this + " " | |
543 | - + Thread.currentThread()); | |
544 | - | |
545 | - return true; | |
546 | - } | |
547 | - | |
548 | - } | |
549 | - | |
550 | - public abstract static class TagOperator implements ITagExpression, ITagOperator<ITagExpression, TagPattern> | |
551 | - { | |
552 | - | |
553 | - public ArrayList<INode<ITagExpression>> expressions = new ArrayList<>(); | |
554 | - public ArrayList<INode<TagPattern>> operators = new ArrayList<>(); | |
555 | - | |
556 | - @Override | |
557 | - public void setExpression(int index, INode<ITagExpression> node) | |
558 | - { | |
559 | - while (expressions.size() <= index) { | |
560 | - expressions.add(null); | |
561 | - } | |
562 | - expressions.set(index, node); | |
563 | - } | |
564 | - | |
565 | - @Override | |
566 | - public void setOperator(int index, INode<TagPattern> node) | |
567 | - { | |
568 | - while (operators.size() <= index) { | |
569 | - operators.add(null); | |
570 | - } | |
571 | - operators.set(index, node); | |
572 | - } | |
573 | - | |
574 | - /** | |
575 | - * @param operator | |
576 | - * @param left | |
577 | - * 常に破壊される。 | |
578 | - * @param right | |
579 | - * 常に破壊されない。 | |
580 | - */ | |
581 | - public void calculate(String operator, StructureComplex left, StructureComplex right) | |
582 | - { | |
583 | - if (operator.equals("^")) { | |
584 | - Exponential.pow(left, right); | |
585 | - return; | |
586 | - } | |
587 | - if (operator.equals("+")) { | |
588 | - left.add(right); | |
589 | - return; | |
590 | - } | |
591 | - if (operator.equals("-")) { | |
592 | - left.sub(right); | |
593 | - return; | |
594 | - } | |
595 | - if (operator.equals("*")) { | |
596 | - left.mul(right); | |
597 | - return; | |
598 | - } | |
599 | - if (operator.equals("/")) { | |
600 | - left.div(right); | |
601 | - return; | |
602 | - } | |
603 | - } | |
604 | - | |
605 | - } | |
606 | - | |
607 | - public static class TagOperatorRight extends TagOperator | |
608 | - { | |
609 | - | |
610 | - @Override | |
611 | - public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
612 | - { | |
613 | - StructureComplex left = new StructureComplex(); | |
614 | - | |
615 | - if (!expressions.get(operators.size()).getTag().calculate(argument, out)) { | |
616 | - return false; | |
617 | - } | |
618 | - | |
619 | - for (int i = operators.size() - 1; i >= 0; i--) { | |
620 | - if (!expressions.get(i).getTag().calculate(argument, left)) { | |
621 | - return false; | |
622 | - } | |
623 | - | |
624 | - String operator = operators.get(i).getTag().child.getTag().string; | |
625 | - | |
626 | - calculate(operator, left, out); | |
627 | - out.set(left); | |
628 | - } | |
629 | - | |
630 | - return true; | |
631 | - } | |
632 | - | |
633 | - @Override | |
634 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
635 | - { | |
636 | - for (int i = 0; i < expressions.size(); i++) { | |
637 | - if (!expressions.get(i).getTag().validate(argument)) return false; | |
638 | - } | |
639 | - return true; | |
640 | - } | |
641 | - | |
642 | - } | |
643 | - | |
644 | - public static class TagOperatorLeft extends TagOperator | |
645 | - { | |
646 | - | |
647 | - @Override | |
648 | - public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
649 | - { | |
650 | - StructureComplex right = new StructureComplex(); | |
651 | - | |
652 | - if (!expressions.get(0).getTag().calculate(argument, out)) { | |
653 | - return false; | |
654 | - } | |
655 | - | |
656 | - for (int i = 0; i < operators.size(); i++) { | |
657 | - if (!expressions.get(i + 1).getTag().calculate(argument, right)) { | |
658 | - return false; | |
659 | - } | |
660 | - | |
661 | - String operator = operators.get(i).getTag().child.getTag().string; | |
662 | - | |
663 | - calculate(operator, out, right); | |
664 | - } | |
665 | - | |
666 | - return true; | |
667 | - } | |
668 | - | |
669 | - @Override | |
670 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
671 | - { | |
672 | - for (int i = 0; i < expressions.size(); i++) { | |
673 | - if (!expressions.get(i).getTag().validate(argument)) return false; | |
674 | - } | |
675 | - return true; | |
676 | - } | |
677 | - | |
678 | - } | |
679 | - | |
680 | - public static class TagBracket implements ITagExpression | |
681 | - { | |
682 | - | |
683 | - public INode<ITagExpression> node; | |
684 | - | |
685 | - @Override | |
686 | - public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
687 | - { | |
688 | - return node.getTag().validate(argument); | |
689 | - } | |
690 | - | |
691 | - @Override | |
692 | - public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
693 | - { | |
694 | - return node.getTag().calculate(argument, out); | |
695 | - } | |
696 | - | |
697 | - } | |
698 | - | |
699 | - public static class TagArguments | |
700 | - { | |
701 | - | |
702 | - public INode<TagArgumentList> nodes; | |
703 | - | |
704 | - } | |
705 | - | |
706 | - public static class TagArgumentList implements ITagOperator<ITagExpression, TagToken> | |
707 | - { | |
708 | - | |
709 | - public ArrayList<INode<ITagExpression>> nodes = new ArrayList<>(); | |
710 | - public ArrayList<INode<TagToken>> operators = new ArrayList<>(); | |
711 | - | |
712 | - @Override | |
713 | - public void setExpression(int index, INode<ITagExpression> node) | |
714 | - { | |
715 | - while (nodes.size() <= index) { | |
716 | - nodes.add(null); | |
717 | - } | |
718 | - nodes.set(index, node); | |
719 | - } | |
720 | - | |
721 | - @Override | |
722 | - public void setOperator(int index, INode<TagToken> node) | |
723 | - { | |
724 | - while (operators.size() <= index) { | |
725 | - operators.add(null); | |
726 | - } | |
727 | - operators.set(index, node); | |
728 | - } | |
354 | + public INode<T> node; | |
729 | 355 | |
730 | 356 | } |
731 | 357 |
@@ -1,91 +0,0 @@ | ||
1 | -package mirrg.game.complexcanvas.wulfenite.script; | |
2 | - | |
3 | -import java.util.ArrayList; | |
4 | -import java.util.regex.Matcher; | |
5 | - | |
6 | -import mirrg.compile.iodine.INode; | |
7 | -import mirrg.compile.iodine.comment.ITagCommented; | |
8 | -import mirrg.compile.iodine.statements.ITagPattern; | |
9 | -import mirrg.compile.iodine.statements.ITagToken; | |
10 | -import mirrg.compile.iodine.statements.connection.ITagParent; | |
11 | - | |
12 | -public class TagsCommented | |
13 | -{ | |
14 | - | |
15 | - public static class TagCommented<T> implements ITagCommented<TagComments, T> | |
16 | - { | |
17 | - | |
18 | - public INode<TagComments> comment; | |
19 | - public INode<T> child; | |
20 | - | |
21 | - @Override | |
22 | - public void setComment(INode<TagComments> comment) | |
23 | - { | |
24 | - this.comment = comment; | |
25 | - } | |
26 | - | |
27 | - @Override | |
28 | - public void setChild(INode<T> child) | |
29 | - { | |
30 | - this.child = child; | |
31 | - } | |
32 | - | |
33 | - } | |
34 | - | |
35 | - public static class TagComments implements ITagParent<TagPatternImpl> | |
36 | - { | |
37 | - | |
38 | - public ArrayList<INode<TagPatternImpl>> nodes = new ArrayList<>(); | |
39 | - | |
40 | - @Override | |
41 | - public void set(int index, INode<TagPatternImpl> node) | |
42 | - { | |
43 | - while (nodes.size() <= index) { | |
44 | - nodes.add(null); | |
45 | - } | |
46 | - nodes.set(index, node); | |
47 | - } | |
48 | - | |
49 | - } | |
50 | - | |
51 | - public static class TagPattern extends TagCommented<TagPatternImpl> | |
52 | - { | |
53 | - | |
54 | - } | |
55 | - | |
56 | - public static class TagPatternImpl implements ITagPattern | |
57 | - { | |
58 | - | |
59 | - public String string; | |
60 | - public Matcher matcher; | |
61 | - | |
62 | - @Override | |
63 | - public void set(String string, Matcher matcher) | |
64 | - { | |
65 | - this.string = string; | |
66 | - this.matcher = matcher; | |
67 | - } | |
68 | - | |
69 | - } | |
70 | - | |
71 | - public static class TagToken extends TagCommented<TagTokenImpl> | |
72 | - { | |
73 | - | |
74 | - } | |
75 | - | |
76 | - public static class TagTokenImpl implements ITagToken | |
77 | - { | |
78 | - | |
79 | - public String string; | |
80 | - public String token; | |
81 | - | |
82 | - @Override | |
83 | - public void set(String string, String token) | |
84 | - { | |
85 | - this.string = string; | |
86 | - this.token = token; | |
87 | - } | |
88 | - | |
89 | - } | |
90 | - | |
91 | -} |
@@ -0,0 +1,627 @@ | ||
1 | +package mirrg.game.complexcanvas.wulfenite.script; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.function.BiPredicate; | |
5 | + | |
6 | +import mirrg.compile.iodine.INode; | |
7 | +import mirrg.compile.iodine.util.ITagOperator; | |
8 | +import mirrg.complex.hydrogen.StructureComplex; | |
9 | +import mirrg.complex.hydrogen.functions.Exponential; | |
10 | +import mirrg.complex.hydrogen.functions.Trigonometry; | |
11 | +import mirrg.game.complexcanvas.wulfenite.script.TagsRunnable.ITagRunnable; | |
12 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.ITagTokenProvider; | |
13 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.TagPattern; | |
14 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.TagToken; | |
15 | + | |
16 | +public class TagsExpression | |
17 | +{ | |
18 | + | |
19 | + public static interface ITagExpression | |
20 | + { | |
21 | + | |
22 | + public boolean validate(ArgumentWulfeniteScriptValidate argument); | |
23 | + | |
24 | + /** | |
25 | + * @param argument | |
26 | + * @param out | |
27 | + * この構文の出力用バッファ。 | |
28 | + * 呼び出し時の値は無意味。 | |
29 | + * @return | |
30 | + */ | |
31 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out); | |
32 | + | |
33 | + } | |
34 | + | |
35 | + public static class TagVariable implements ITagExpression | |
36 | + { | |
37 | + | |
38 | + public INode<TagPattern> node; | |
39 | + public int index; | |
40 | + | |
41 | + @Override | |
42 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
43 | + { | |
44 | + out.set(argument.stack.variables[index]); | |
45 | + return true; | |
46 | + } | |
47 | + | |
48 | + @Override | |
49 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
50 | + { | |
51 | + boolean flag = true; | |
52 | + String name = node.getTag().child.getTag().string; | |
53 | + | |
54 | + Integer index2 = argument.stackFrameRoot.getStackFrame().getVariableIndex(name); | |
55 | + if (index2 == null) { | |
56 | + argument.addMessage(node, "未宣言の変数です: " + name); | |
57 | + flag = false; | |
58 | + } else { | |
59 | + index = index2; | |
60 | + } | |
61 | + | |
62 | + return flag; | |
63 | + } | |
64 | + | |
65 | + } | |
66 | + | |
67 | + public static class TagNumber implements ITagExpression | |
68 | + { | |
69 | + | |
70 | + public TagPattern pattern; | |
71 | + public StructureComplex value; | |
72 | + | |
73 | + public TagNumber(TagPattern pattern) | |
74 | + { | |
75 | + this.pattern = pattern; | |
76 | + } | |
77 | + | |
78 | + @Override | |
79 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
80 | + { | |
81 | + out.set(value); | |
82 | + return true; | |
83 | + } | |
84 | + | |
85 | + @Override | |
86 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
87 | + { | |
88 | + String a = pattern.child.getTag().matcher.group(1); | |
89 | + String b = pattern.child.getTag().matcher.group(2); | |
90 | + String c = pattern.child.getTag().matcher.group(3); | |
91 | + String d = pattern.child.getTag().matcher.group(4); | |
92 | + | |
93 | + StringBuilder sb = new StringBuilder(); | |
94 | + sb.append(a); | |
95 | + if (b != null) { | |
96 | + sb.append("."); | |
97 | + sb.append(b); | |
98 | + } | |
99 | + if (c != null) { | |
100 | + sb.append("E"); | |
101 | + sb.append(c); | |
102 | + } | |
103 | + double value2 = Double.parseDouble(sb.toString()); | |
104 | + | |
105 | + value = new StructureComplex(); | |
106 | + if (d != null) { | |
107 | + value.set(0, value2); | |
108 | + } else { | |
109 | + value.set(value2, 0); | |
110 | + } | |
111 | + | |
112 | + System.out.println("" | |
113 | + + this + " " | |
114 | + + Thread.currentThread()); | |
115 | + | |
116 | + return true; | |
117 | + } | |
118 | + | |
119 | + } | |
120 | + | |
121 | + public static class TagFunction implements ITagExpression | |
122 | + { | |
123 | + | |
124 | + public INode<TagPattern> nodeMethod; | |
125 | + public INode<TagArgumentList> nodeArguments; | |
126 | + public BiPredicate<ArgumentWulfeniteScript, StructureComplex> method; | |
127 | + public int[] registers; | |
128 | + | |
129 | + @Override | |
130 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
131 | + { | |
132 | + if (nodeArguments.getTag().nodes == null) { | |
133 | + argument.addMessage(nodeMethod, "引数の数が不正です: " + 0); | |
134 | + return false; | |
135 | + } | |
136 | + | |
137 | + if (nodeArguments.getTag().nodes.size() != 1) { | |
138 | + argument.addMessage(nodeMethod, "引数の数が不正です: " + nodeArguments.getTag().nodes.size()); | |
139 | + return false; | |
140 | + } | |
141 | + | |
142 | + registers = new int[nodeArguments.getTag().nodes.size()]; | |
143 | + for (int i = 0; i < nodeArguments.getTag().nodes.size(); i++) { | |
144 | + registers[i] = argument.registerFrameRoot.getRegisterFrame().defineRegister(); | |
145 | + } | |
146 | + | |
147 | + INode<ITagExpression> nodeArgument = nodeArguments.getTag().nodes.get(0); | |
148 | + | |
149 | + if (!nodeArgument.getTag().validate(argument)) return false; | |
150 | + | |
151 | + String string = nodeMethod.getTag().child.getTag().string; | |
152 | + | |
153 | + if (string.equals("pow")) { | |
154 | + method = (argument2, out) -> { | |
155 | + nodeArgument.getTag().calculate(argument2, out); | |
156 | + Exponential.pow(out, 2); | |
157 | + return true; | |
158 | + }; | |
159 | + } else if (string.equals("exp")) { | |
160 | + method = (argument2, out) -> { | |
161 | + nodeArgument.getTag().calculate(argument2, out); | |
162 | + Exponential.exp(out); | |
163 | + return true; | |
164 | + }; | |
165 | + } else if (string.equals("log")) { | |
166 | + method = (argument2, out) -> { | |
167 | + nodeArgument.getTag().calculate(argument2, out); | |
168 | + Exponential.log(out); | |
169 | + return true; | |
170 | + }; | |
171 | + } else if (string.equals("sin")) { | |
172 | + method = (argument2, out) -> { | |
173 | + nodeArgument.getTag().calculate(argument2, out); | |
174 | + Trigonometry.sin(out); | |
175 | + return true; | |
176 | + }; | |
177 | + } else if (string.equals("cos")) { | |
178 | + method = (argument2, out) -> { | |
179 | + nodeArgument.getTag().calculate(argument2, out); | |
180 | + Trigonometry.cos(out); | |
181 | + return true; | |
182 | + }; | |
183 | + } else if (string.equals("tan")) { | |
184 | + method = (argument2, out) -> { | |
185 | + nodeArgument.getTag().calculate(argument2, out); | |
186 | + Trigonometry.tan(out); | |
187 | + return true; | |
188 | + }; | |
189 | + } else if (string.equals("sinh")) { | |
190 | + method = (argument2, out) -> { | |
191 | + nodeArgument.getTag().calculate(argument2, out); | |
192 | + Trigonometry.sinh(out); | |
193 | + return true; | |
194 | + }; | |
195 | + } else if (string.equals("cosh")) { | |
196 | + method = (argument2, out) -> { | |
197 | + nodeArgument.getTag().calculate(argument2, out); | |
198 | + Trigonometry.cosh(out); | |
199 | + return true; | |
200 | + }; | |
201 | + } else if (string.equals("tanh")) { | |
202 | + method = (argument2, out) -> { | |
203 | + nodeArgument.getTag().calculate(argument2, out); | |
204 | + Trigonometry.tanh(out); | |
205 | + return true; | |
206 | + }; | |
207 | + } else if (string.equals("inv")) { | |
208 | + method = (argument2, out) -> { | |
209 | + nodeArgument.getTag().calculate(argument2, out); | |
210 | + out.inv(); | |
211 | + return true; | |
212 | + }; | |
213 | + } else if (string.equals("neg")) { | |
214 | + method = (argument2, out) -> { | |
215 | + nodeArgument.getTag().calculate(argument2, out); | |
216 | + out.neg(); | |
217 | + return true; | |
218 | + }; | |
219 | + } else if (string.equals("con")) { | |
220 | + method = (argument2, out) -> { | |
221 | + nodeArgument.getTag().calculate(argument2, out); | |
222 | + out.con(); | |
223 | + return true; | |
224 | + }; | |
225 | + } else if (string.equals("abs")) { | |
226 | + method = (argument2, out) -> { | |
227 | + nodeArgument.getTag().calculate(argument2, out); | |
228 | + out.set(out.getAbstract(), 0); | |
229 | + return true; | |
230 | + }; | |
231 | + } else if (string.equals("abs2")) { | |
232 | + method = (argument2, out) -> { | |
233 | + nodeArgument.getTag().calculate(argument2, out); | |
234 | + out.set(out.getAbstract2(), 0); | |
235 | + return true; | |
236 | + }; | |
237 | + } else if (string.equals("arg")) { | |
238 | + method = (argument2, out) -> { | |
239 | + nodeArgument.getTag().calculate(argument2, out); | |
240 | + out.set(out.getArgument(), 0); | |
241 | + return true; | |
242 | + }; | |
243 | + } else if (string.equals("re")) { | |
244 | + method = (argument2, out) -> { | |
245 | + nodeArgument.getTag().calculate(argument2, out); | |
246 | + out.set(out.re, 0); | |
247 | + return true; | |
248 | + }; | |
249 | + } else if (string.equals("im")) { | |
250 | + method = (argument2, out) -> { | |
251 | + nodeArgument.getTag().calculate(argument2, out); | |
252 | + out.set(out.im, 0); | |
253 | + return true; | |
254 | + }; | |
255 | + } else { | |
256 | + argument.addMessage(nodeMethod, "不明な関数です: " + string); | |
257 | + return false; | |
258 | + } | |
259 | + | |
260 | + return true; | |
261 | + } | |
262 | + | |
263 | + @Override | |
264 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
265 | + { | |
266 | + return method.test(argument, out); | |
267 | + } | |
268 | + | |
269 | + public static class TagArgumentList implements ITagOperator<ITagExpression, TagToken> | |
270 | + { | |
271 | + | |
272 | + public ArrayList<INode<ITagExpression>> nodes = new ArrayList<>(); | |
273 | + public ArrayList<INode<TagToken>> operators = new ArrayList<>(); | |
274 | + | |
275 | + @Override | |
276 | + public void setExpression(int index, INode<ITagExpression> node) | |
277 | + { | |
278 | + while (nodes.size() <= index) { | |
279 | + nodes.add(null); | |
280 | + } | |
281 | + nodes.set(index, node); | |
282 | + } | |
283 | + | |
284 | + @Override | |
285 | + public void setOperator(int index, INode<TagToken> node) | |
286 | + { | |
287 | + while (operators.size() <= index) { | |
288 | + operators.add(null); | |
289 | + } | |
290 | + operators.set(index, node); | |
291 | + } | |
292 | + | |
293 | + } | |
294 | + | |
295 | + } | |
296 | + | |
297 | + public abstract static class TagOperator implements ITagExpression, ITagOperator<ITagExpression, ITagTokenProvider> | |
298 | + { | |
299 | + | |
300 | + public ArrayList<INode<ITagExpression>> nodeExpressions = new ArrayList<>(); | |
301 | + public ArrayList<INode<ITagTokenProvider>> nodeOperators = new ArrayList<>(); | |
302 | + public ITagExpression[] expressions; | |
303 | + public int[] operators; | |
304 | + public int register1; | |
305 | + | |
306 | + @Override | |
307 | + public void setExpression(int index, INode<ITagExpression> node) | |
308 | + { | |
309 | + while (nodeExpressions.size() <= index) { | |
310 | + nodeExpressions.add(null); | |
311 | + } | |
312 | + nodeExpressions.set(index, node); | |
313 | + } | |
314 | + | |
315 | + @Override | |
316 | + public void setOperator(int index, INode<ITagTokenProvider> node) | |
317 | + { | |
318 | + while (nodeOperators.size() <= index) { | |
319 | + nodeOperators.add(null); | |
320 | + } | |
321 | + nodeOperators.set(index, node); | |
322 | + } | |
323 | + | |
324 | + /** | |
325 | + * @param operator | |
326 | + * @param left | |
327 | + * 常に破壊される。 | |
328 | + * @param right | |
329 | + * 常に破壊されない。 | |
330 | + */ | |
331 | + public void calculate(int operator, StructureComplex left, StructureComplex right) | |
332 | + { | |
333 | + switch (operator) { | |
334 | + case 0: | |
335 | + Exponential.pow(left, right); | |
336 | + return; | |
337 | + case 1: | |
338 | + left.add(right); | |
339 | + return; | |
340 | + case 2: | |
341 | + left.sub(right); | |
342 | + return; | |
343 | + case 3: | |
344 | + left.mul(right); | |
345 | + return; | |
346 | + case 4: | |
347 | + left.div(right); | |
348 | + return; | |
349 | + case 5: | |
350 | + if (left.re != 0) { | |
351 | + left.re = 1; | |
352 | + } else { | |
353 | + left.re = right.re != 0 ? 1 : 0; | |
354 | + } | |
355 | + left.im = 0; | |
356 | + return; | |
357 | + case 6: | |
358 | + if (left.re != 0) { | |
359 | + left.re = right.re != 0 ? 1 : 0; | |
360 | + } else { | |
361 | + left.re = 0; | |
362 | + } | |
363 | + left.im = 0; | |
364 | + return; | |
365 | + case 7: | |
366 | + left.re = left.re < right.re ? 1 : 0; | |
367 | + left.im = 0; | |
368 | + return; | |
369 | + case 8: | |
370 | + left.re = left.re > right.re ? 1 : 0; | |
371 | + left.im = 0; | |
372 | + return; | |
373 | + case 9: | |
374 | + left.re = left.re <= right.re ? 1 : 0; | |
375 | + left.im = 0; | |
376 | + return; | |
377 | + case 10: | |
378 | + left.re = left.re >= right.re ? 1 : 0; | |
379 | + left.im = 0; | |
380 | + return; | |
381 | + case 11: | |
382 | + left.re = left.re == right.re && left.im == right.im ? 1 : 0; | |
383 | + left.im = 0; | |
384 | + return; | |
385 | + case 12: | |
386 | + left.re = left.re != right.re || left.im != right.im ? 1 : 0; | |
387 | + left.im = 0; | |
388 | + return; | |
389 | + } | |
390 | + } | |
391 | + | |
392 | + @Override | |
393 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
394 | + { | |
395 | + boolean flag = true; | |
396 | + | |
397 | + register1 = argument.registerFrameRoot.getRegisterFrame().defineRegister(); | |
398 | + | |
399 | + operators = new int[nodeOperators.size()]; | |
400 | + | |
401 | + for (int i = 0; i < nodeOperators.size(); i++) { | |
402 | + INode<ITagTokenProvider> operator = nodeOperators.get(i); | |
403 | + | |
404 | + String token = operator.getTag().getToken(); | |
405 | + int operatorCode = 0; | |
406 | + | |
407 | + operators[i] = operatorCode; | |
408 | + if (token.equals("^")) continue; | |
409 | + operatorCode++; | |
410 | + | |
411 | + operators[i] = operatorCode; | |
412 | + if (token.equals("+")) continue; | |
413 | + operatorCode++; | |
414 | + | |
415 | + operators[i] = operatorCode; | |
416 | + if (token.equals("-")) continue; | |
417 | + operatorCode++; | |
418 | + | |
419 | + operators[i] = operatorCode; | |
420 | + if (token.equals("*")) continue; | |
421 | + operatorCode++; | |
422 | + | |
423 | + operators[i] = operatorCode; | |
424 | + if (token.equals("/")) continue; | |
425 | + operatorCode++; | |
426 | + | |
427 | + operators[i] = operatorCode; | |
428 | + if (token.equals("||")) continue; | |
429 | + operatorCode++; | |
430 | + | |
431 | + operators[i] = operatorCode; | |
432 | + if (token.equals("&&")) continue; | |
433 | + operatorCode++; | |
434 | + | |
435 | + operators[i] = operatorCode; | |
436 | + if (token.equals("<")) continue; | |
437 | + operatorCode++; | |
438 | + | |
439 | + operators[i] = operatorCode; | |
440 | + if (token.equals(">")) continue; | |
441 | + operatorCode++; | |
442 | + | |
443 | + operators[i] = operatorCode; | |
444 | + if (token.equals("<=")) continue; | |
445 | + operatorCode++; | |
446 | + | |
447 | + operators[i] = operatorCode; | |
448 | + if (token.equals(">=")) continue; | |
449 | + operatorCode++; | |
450 | + | |
451 | + operators[i] = operatorCode; | |
452 | + if (token.equals("==")) continue; | |
453 | + operatorCode++; | |
454 | + | |
455 | + operators[i] = operatorCode; | |
456 | + if (token.equals("!=")) continue; | |
457 | + operatorCode++; | |
458 | + | |
459 | + flag = false; | |
460 | + } | |
461 | + | |
462 | + expressions = new ITagExpression[nodeExpressions.size()]; | |
463 | + | |
464 | + for (int i = 0; i < nodeExpressions.size(); i++) { | |
465 | + INode<ITagExpression> expression = nodeExpressions.get(i); | |
466 | + | |
467 | + expressions[i] = expression.getTag(); | |
468 | + | |
469 | + if (!expression.getTag().validate(argument)) flag = false; | |
470 | + } | |
471 | + | |
472 | + return flag; | |
473 | + } | |
474 | + | |
475 | + } | |
476 | + | |
477 | + public static class TagOperatorRight extends TagOperator | |
478 | + { | |
479 | + | |
480 | + @Override | |
481 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
482 | + { | |
483 | + | |
484 | + if (!expressions[operators.length].calculate(argument, out)) { | |
485 | + return false; | |
486 | + } | |
487 | + | |
488 | + for (int i = operators.length - 1; i >= 0; i--) { | |
489 | + if (!expressions[i].calculate(argument, argument.register.registers[register1])) { | |
490 | + return false; | |
491 | + } | |
492 | + | |
493 | + calculate(operators[i], argument.register.registers[register1], out); | |
494 | + out.set(argument.register.registers[register1]); | |
495 | + } | |
496 | + | |
497 | + return true; | |
498 | + } | |
499 | + | |
500 | + } | |
501 | + | |
502 | + public static class TagOperatorLeft extends TagOperator | |
503 | + { | |
504 | + | |
505 | + @Override | |
506 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
507 | + { | |
508 | + | |
509 | + if (!expressions[0].calculate(argument, out)) { | |
510 | + return false; | |
511 | + } | |
512 | + | |
513 | + for (int i = 0; i < operators.length; i++) { | |
514 | + if (!expressions[i + 1].calculate(argument, argument.register.registers[register1])) { | |
515 | + return false; | |
516 | + } | |
517 | + | |
518 | + calculate(operators[i], out, argument.register.registers[register1]); | |
519 | + } | |
520 | + | |
521 | + return true; | |
522 | + } | |
523 | + | |
524 | + } | |
525 | + | |
526 | + public static class TagNegation implements ITagExpression | |
527 | + { | |
528 | + | |
529 | + public boolean isBoolean = false; | |
530 | + public INode<ITagExpression> node; | |
531 | + | |
532 | + @Override | |
533 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
534 | + { | |
535 | + return node.getTag().validate(argument); | |
536 | + } | |
537 | + | |
538 | + @Override | |
539 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
540 | + { | |
541 | + if (isBoolean) { | |
542 | + if (!node.getTag().calculate(argument, out)) return false; | |
543 | + out.set(out.re == 0 ? 1 : 0, 0); | |
544 | + return true; | |
545 | + } else { | |
546 | + if (!node.getTag().calculate(argument, out)) return false; | |
547 | + out.neg(); | |
548 | + return true; | |
549 | + } | |
550 | + } | |
551 | + | |
552 | + } | |
553 | + | |
554 | + public static class TagIif implements ITagExpression | |
555 | + { | |
556 | + | |
557 | + public INode<ITagExpression> nodeCondition; | |
558 | + public INode<ITagExpression> nodeTrue; | |
559 | + public INode<ITagExpression> nodeFalse; | |
560 | + public int register1; | |
561 | + | |
562 | + @Override | |
563 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
564 | + { | |
565 | + boolean flag = true; | |
566 | + | |
567 | + register1 = argument.registerFrameRoot.getRegisterFrame().defineRegister(); | |
568 | + if (!nodeCondition.getTag().validate(argument)) flag = false; | |
569 | + | |
570 | + if (!nodeTrue.getTag().validate(argument)) flag = false; | |
571 | + if (!nodeFalse.getTag().validate(argument)) flag = false; | |
572 | + | |
573 | + return flag; | |
574 | + } | |
575 | + | |
576 | + @Override | |
577 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
578 | + { | |
579 | + if (!nodeCondition.getTag().calculate( | |
580 | + argument, argument.register.registers[register1])) return false; | |
581 | + | |
582 | + if (argument.register.registers[register1].re != 0) { | |
583 | + return nodeTrue.getTag().calculate(argument, out); | |
584 | + } else { | |
585 | + return nodeFalse.getTag().calculate(argument, out); | |
586 | + } | |
587 | + } | |
588 | + | |
589 | + } | |
590 | + | |
591 | + public static class TagDo implements ITagExpression | |
592 | + { | |
593 | + | |
594 | + public INode<ITagRunnable> nodeRunnable; | |
595 | + public INode<ITagExpression> nodeLast; | |
596 | + public ITagRunnable tagRunnable; | |
597 | + public ITagExpression tagLast; | |
598 | + | |
599 | + @Override | |
600 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
601 | + { | |
602 | + boolean flag = true; | |
603 | + | |
604 | + argument.stackFrameRoot.pushStackFrame(); | |
605 | + argument.registerFrameRoot.pushRegisterFrame(); | |
606 | + | |
607 | + tagRunnable = nodeRunnable.getTag(); | |
608 | + if (!tagRunnable.validate(argument)) flag = false; | |
609 | + tagLast = nodeLast.getTag(); | |
610 | + if (!tagLast.validate(argument)) flag = false; | |
611 | + | |
612 | + argument.stackFrameRoot.popStackFrame(); | |
613 | + argument.registerFrameRoot.popRegisterFrame(); | |
614 | + | |
615 | + return flag; | |
616 | + } | |
617 | + | |
618 | + @Override | |
619 | + public boolean calculate(ArgumentWulfeniteScript argument, StructureComplex out) | |
620 | + { | |
621 | + if (!tagRunnable.invoke(argument)) return false; | |
622 | + return tagLast.calculate(argument, out); | |
623 | + } | |
624 | + | |
625 | + } | |
626 | + | |
627 | +} |
@@ -0,0 +1,295 @@ | ||
1 | +package mirrg.game.complexcanvas.wulfenite.script; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | + | |
5 | +import mirrg.compile.iodine.INode; | |
6 | +import mirrg.compile.iodine.statements.connection.ITagParent; | |
7 | +import mirrg.game.complexcanvas.wulfenite.script.TagsExpression.ITagExpression; | |
8 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.ITagTokenProvider; | |
9 | +import mirrg.game.complexcanvas.wulfenite.script.TagsTokenProvider.TagPattern; | |
10 | + | |
11 | +public class TagsRunnable | |
12 | +{ | |
13 | + | |
14 | + public static interface ITagRunnable extends IWulfeniteScript | |
15 | + { | |
16 | + | |
17 | + } | |
18 | + | |
19 | + public static class TagStackFrame implements ITagRunnable | |
20 | + { | |
21 | + | |
22 | + public INode<ITagRunnable> node; | |
23 | + public ITagRunnable tag; | |
24 | + | |
25 | + @Override | |
26 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
27 | + { | |
28 | + boolean flag = true; | |
29 | + | |
30 | + argument.stackFrameRoot.pushStackFrame(); | |
31 | + argument.registerFrameRoot.pushRegisterFrame(); | |
32 | + | |
33 | + tag = node.getTag(); | |
34 | + if (!tag.validate(argument)) flag = false; | |
35 | + | |
36 | + argument.stackFrameRoot.popStackFrame(); | |
37 | + argument.registerFrameRoot.popRegisterFrame(); | |
38 | + | |
39 | + return flag; | |
40 | + } | |
41 | + | |
42 | + @Override | |
43 | + public boolean invoke(ArgumentWulfeniteScript argument) | |
44 | + { | |
45 | + if (!tag.invoke(argument)) return false; | |
46 | + return true; | |
47 | + } | |
48 | + | |
49 | + } | |
50 | + | |
51 | + public static class TagBlock implements ITagRunnable, ITagParent<ITagRunnable> | |
52 | + { | |
53 | + | |
54 | + public ArrayList<INode<ITagRunnable>> nodes = new ArrayList<>(); | |
55 | + public ITagRunnable[] tags; | |
56 | + | |
57 | + @Override | |
58 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
59 | + { | |
60 | + boolean flag = true; | |
61 | + | |
62 | + tags = new ITagRunnable[nodes.size()]; | |
63 | + for (int i = 0; i < nodes.size(); i++) { | |
64 | + tags[i] = nodes.get(i).getTag(); | |
65 | + | |
66 | + if (!tags[i].validate(argument)) flag = false; | |
67 | + } | |
68 | + | |
69 | + return flag; | |
70 | + } | |
71 | + | |
72 | + @Override | |
73 | + public boolean invoke(ArgumentWulfeniteScript argument) | |
74 | + { | |
75 | + for (ITagRunnable tag : tags) { | |
76 | + if (!tag.invoke(argument)) return false; | |
77 | + } | |
78 | + return true; | |
79 | + } | |
80 | + | |
81 | + @Override | |
82 | + public void set(int index, INode<ITagRunnable> node) | |
83 | + { | |
84 | + while (index >= nodes.size()) { | |
85 | + nodes.add(null); | |
86 | + } | |
87 | + nodes.set(index, node); | |
88 | + } | |
89 | + | |
90 | + } | |
91 | + | |
92 | + public static class TagEmptyStatement implements ITagRunnable | |
93 | + { | |
94 | + | |
95 | + public ITagTokenProvider tag; | |
96 | + | |
97 | + public TagEmptyStatement(ITagTokenProvider tag) | |
98 | + { | |
99 | + this.tag = tag; | |
100 | + } | |
101 | + | |
102 | + @Override | |
103 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
104 | + { | |
105 | + return true; | |
106 | + } | |
107 | + | |
108 | + @Override | |
109 | + public boolean invoke(ArgumentWulfeniteScript argument) | |
110 | + { | |
111 | + return true; | |
112 | + } | |
113 | + | |
114 | + } | |
115 | + | |
116 | + public static abstract class TagAssignmentBase implements ITagRunnable | |
117 | + { | |
118 | + | |
119 | + public INode<ITagExpression> node = null; | |
120 | + public INode<TagPattern> nodeVariable = null; | |
121 | + public ITagExpression tag = null; | |
122 | + public int index; | |
123 | + public int register1; | |
124 | + | |
125 | + @Override | |
126 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
127 | + { | |
128 | + boolean flag = true; | |
129 | + | |
130 | + register1 = argument.registerFrameRoot.getRegisterFrame().defineRegister(); | |
131 | + | |
132 | + if (!validateIndex(argument)) flag = false; | |
133 | + | |
134 | + if (node != null) { | |
135 | + tag = node.getTag(); | |
136 | + if (!tag.validate(argument)) flag = false; | |
137 | + } | |
138 | + | |
139 | + return flag; | |
140 | + } | |
141 | + | |
142 | + protected abstract boolean validateIndex(ArgumentWulfeniteScriptValidate argument); | |
143 | + | |
144 | + @Override | |
145 | + public boolean invoke(ArgumentWulfeniteScript argument) | |
146 | + { | |
147 | + if (tag != null) { | |
148 | + if (!tag.calculate(argument, argument.register.registers[register1])) return false; | |
149 | + argument.stack.variables[index].set(argument.register.registers[register1]); | |
150 | + } | |
151 | + return true; | |
152 | + } | |
153 | + | |
154 | + } | |
155 | + | |
156 | + public static class TagAssignment extends TagAssignmentBase | |
157 | + { | |
158 | + | |
159 | + @Override | |
160 | + protected boolean validateIndex(ArgumentWulfeniteScriptValidate argument) | |
161 | + { | |
162 | + String name = nodeVariable == null ? "_" : nodeVariable.getTag().child.getTag().string; | |
163 | + | |
164 | + Integer index2 = argument.stackFrameRoot.getStackFrame().getVariableIndex(name); | |
165 | + if (index2 == null) { | |
166 | + argument.addMessage(node, "未宣言の変数です: " + name); | |
167 | + return false; | |
168 | + } else { | |
169 | + index = index2; | |
170 | + } | |
171 | + | |
172 | + return true; | |
173 | + } | |
174 | + | |
175 | + } | |
176 | + | |
177 | + public static class TagDefineVariable extends TagAssignmentBase | |
178 | + { | |
179 | + | |
180 | + @Override | |
181 | + protected boolean validateIndex(ArgumentWulfeniteScriptValidate argument) | |
182 | + { | |
183 | + String name = nodeVariable == null ? "_" : nodeVariable.getTag().child.getTag().string; | |
184 | + | |
185 | + Integer index2 = argument.stackFrameRoot.getStackFrame().defineVariable(name); | |
186 | + if (index2 == null) { | |
187 | + argument.addMessage(nodeVariable, "重複する変数名です: " + name); | |
188 | + return false; | |
189 | + } else { | |
190 | + index = index2; | |
191 | + } | |
192 | + | |
193 | + return true; | |
194 | + } | |
195 | + | |
196 | + } | |
197 | + | |
198 | + public static class TagWhile implements ITagRunnable | |
199 | + { | |
200 | + | |
201 | + public INode<ITagExpression> nodeCondition; | |
202 | + public INode<ITagRunnable> nodeRunnable; | |
203 | + public ITagExpression tagCondition; | |
204 | + public ITagRunnable tagRunnable; | |
205 | + public int register1; | |
206 | + | |
207 | + @Override | |
208 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
209 | + { | |
210 | + boolean flag = true; | |
211 | + | |
212 | + register1 = argument.registerFrameRoot.getRegisterFrame().defineRegister(); | |
213 | + | |
214 | + tagCondition = nodeCondition.getTag(); | |
215 | + if (!tagCondition.validate(argument)) flag = false; | |
216 | + tagRunnable = nodeRunnable.getTag(); | |
217 | + if (!tagRunnable.validate(argument)) flag = false; | |
218 | + | |
219 | + return flag; | |
220 | + } | |
221 | + | |
222 | + @Override | |
223 | + public boolean invoke(ArgumentWulfeniteScript argument) | |
224 | + { | |
225 | + while (true) { | |
226 | + if (!tagCondition.calculate(argument, argument.register.registers[register1])) return false; | |
227 | + if (argument.register.registers[register1].re != 0) { | |
228 | + if (!tagRunnable.invoke(argument)) return false; | |
229 | + } else { | |
230 | + break; | |
231 | + } | |
232 | + } | |
233 | + return true; | |
234 | + } | |
235 | + | |
236 | + } | |
237 | + | |
238 | + public static class TagFor implements ITagRunnable | |
239 | + { | |
240 | + | |
241 | + public INode<ITagRunnable> nodeInitialize; | |
242 | + public INode<ITagExpression> nodeCondition; | |
243 | + public INode<ITagRunnable> nodeIncrement; | |
244 | + public INode<ITagRunnable> nodeRunnable; | |
245 | + public ITagRunnable tagInitialize; | |
246 | + public ITagExpression tagCondition; | |
247 | + public ITagRunnable tagIncrement; | |
248 | + public ITagRunnable tagRunnable; | |
249 | + public int register1; | |
250 | + | |
251 | + @Override | |
252 | + public boolean validate(ArgumentWulfeniteScriptValidate argument) | |
253 | + { | |
254 | + boolean flag = true; | |
255 | + | |
256 | + argument.stackFrameRoot.pushStackFrame(); | |
257 | + argument.registerFrameRoot.pushRegisterFrame(); | |
258 | + | |
259 | + register1 = argument.registerFrameRoot.getRegisterFrame().defineRegister(); | |
260 | + | |
261 | + tagInitialize = nodeInitialize.getTag(); | |
262 | + if (!tagInitialize.validate(argument)) flag = false; | |
263 | + tagCondition = nodeCondition.getTag(); | |
264 | + if (!tagCondition.validate(argument)) flag = false; | |
265 | + tagIncrement = nodeIncrement.getTag(); | |
266 | + if (!tagIncrement.validate(argument)) flag = false; | |
267 | + tagRunnable = nodeRunnable.getTag(); | |
268 | + if (!tagRunnable.validate(argument)) flag = false; | |
269 | + | |
270 | + argument.stackFrameRoot.popStackFrame(); | |
271 | + argument.registerFrameRoot.popRegisterFrame(); | |
272 | + | |
273 | + return flag; | |
274 | + } | |
275 | + | |
276 | + @Override | |
277 | + public boolean invoke(ArgumentWulfeniteScript argument) | |
278 | + { | |
279 | + if (!tagInitialize.invoke(argument)) return false; | |
280 | + | |
281 | + while (true) { | |
282 | + if (!tagCondition.calculate(argument, argument.register.registers[register1])) return false; | |
283 | + if (argument.register.registers[register1].re != 0) { | |
284 | + if (!tagRunnable.invoke(argument)) return false; | |
285 | + } else { | |
286 | + break; | |
287 | + } | |
288 | + if (!tagIncrement.invoke(argument)) return false; | |
289 | + } | |
290 | + return true; | |
291 | + } | |
292 | + | |
293 | + } | |
294 | + | |
295 | +} |
@@ -0,0 +1,110 @@ | ||
1 | +package mirrg.game.complexcanvas.wulfenite.script; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.regex.Matcher; | |
5 | + | |
6 | +import mirrg.compile.iodine.INode; | |
7 | +import mirrg.compile.iodine.comment.ITagCommented; | |
8 | +import mirrg.compile.iodine.statements.ITagPattern; | |
9 | +import mirrg.compile.iodine.statements.ITagToken; | |
10 | +import mirrg.compile.iodine.statements.connection.ITagParent; | |
11 | + | |
12 | +public class TagsTokenProvider | |
13 | +{ | |
14 | + | |
15 | + public static interface ITagTokenProvider | |
16 | + { | |
17 | + | |
18 | + public String getToken(); | |
19 | + | |
20 | + } | |
21 | + | |
22 | + public static class TagCommented<T> implements ITagCommented<TagComments, T> | |
23 | + { | |
24 | + | |
25 | + public INode<TagComments> comment; | |
26 | + public INode<T> child; | |
27 | + | |
28 | + @Override | |
29 | + public void setComment(INode<TagComments> comment) | |
30 | + { | |
31 | + this.comment = comment; | |
32 | + } | |
33 | + | |
34 | + @Override | |
35 | + public void setChild(INode<T> child) | |
36 | + { | |
37 | + this.child = child; | |
38 | + } | |
39 | + | |
40 | + } | |
41 | + | |
42 | + public static class TagComments implements ITagParent<TagPatternImpl> | |
43 | + { | |
44 | + | |
45 | + public ArrayList<INode<TagPatternImpl>> nodes = new ArrayList<>(); | |
46 | + | |
47 | + @Override | |
48 | + public void set(int index, INode<TagPatternImpl> node) | |
49 | + { | |
50 | + while (nodes.size() <= index) { | |
51 | + nodes.add(null); | |
52 | + } | |
53 | + nodes.set(index, node); | |
54 | + } | |
55 | + | |
56 | + } | |
57 | + | |
58 | + public static class TagPattern extends TagCommented<TagPatternImpl> implements ITagTokenProvider | |
59 | + { | |
60 | + | |
61 | + @Override | |
62 | + public String getToken() | |
63 | + { | |
64 | + return child.getTag().string; | |
65 | + } | |
66 | + | |
67 | + } | |
68 | + | |
69 | + public static class TagPatternImpl implements ITagPattern | |
70 | + { | |
71 | + | |
72 | + public String string; | |
73 | + public Matcher matcher; | |
74 | + | |
75 | + @Override | |
76 | + public void set(String string, Matcher matcher) | |
77 | + { | |
78 | + this.string = string; | |
79 | + this.matcher = matcher; | |
80 | + } | |
81 | + | |
82 | + } | |
83 | + | |
84 | + public static class TagToken extends TagCommented<TagTokenImpl> implements ITagTokenProvider | |
85 | + { | |
86 | + | |
87 | + @Override | |
88 | + public String getToken() | |
89 | + { | |
90 | + return child.getTag().string; | |
91 | + } | |
92 | + | |
93 | + } | |
94 | + | |
95 | + public static class TagTokenImpl implements ITagToken | |
96 | + { | |
97 | + | |
98 | + public String string; | |
99 | + public String token; | |
100 | + | |
101 | + @Override | |
102 | + public void set(String string, String token) | |
103 | + { | |
104 | + this.string = string; | |
105 | + this.token = token; | |
106 | + } | |
107 | + | |
108 | + } | |
109 | + | |
110 | +} |