EOS 2  1.1.0
Einfache Objektbasierte Sprache
Program.java
gehe zur Dokumentation dieser Datei
1 package de.lathanda.eos.baseparser;
2 
3 import java.util.ArrayList;
4 import java.util.LinkedList;
5 import java.util.TreeMap;
6 
7 import de.lathanda.eos.baseparser.exceptions.DoubleClassDeclarationException;
8 import de.lathanda.eos.baseparser.exceptions.TranslationException;
9 import de.lathanda.eos.vm.AbstractMachine;
10 import de.lathanda.eos.vm.Command;
11 import de.lathanda.eos.vm.DebugPoint;
12 import de.lathanda.eos.vm.ErrorInformation;
13 import de.lathanda.eos.vm.MProcedure;
14 import de.lathanda.eos.vm.Machine;
15 import de.lathanda.eos.vm.Marker;
16 import de.lathanda.eos.vm.PrettyPrinter;
17 import de.lathanda.eos.vm.ReservedVariables;
18 import de.lathanda.eos.vm.commands.CreateVariable;
19 
25 public class Program implements AbstractProgram {
26  private final ParserFactory parserFactory;
27  private final String defaultWindowName;
28  private final boolean lockProperties;
29  private final static TreeMap<String, Type> guessTable = new TreeMap<>();
30  private final Sequence program;
31  private final LinkedList<SubRoutine> sub;
32  private final TreeMap<String, UserClass> userclass;
33  private final LinkedList<MarkedNode> nodeList;
34  private final LinkedList<InfoToken> tokenList;
35  private final Environment env;
36  private final String source;
37  private final PrettyPrinter prettyPrinter;
38  private final Machine machine;
39  private BasicParser parser;
40  public Program(Program org) {
41  this(org.parserFactory, org.defaultWindowName, org.lockProperties);
42  }
43  public Program(ParserFactory parserFactory, String defaultWindowName, boolean lockProperties) {
44  this.defaultWindowName = defaultWindowName;
45  this.lockProperties = lockProperties;
46  this.parserFactory = parserFactory;
47  this.machine = new Machine();
48  this.program = new Sequence();
49  this.prettyPrinter = new PrettyPrinter("");
50  this.source = "";
51  sub = new LinkedList<>();
52  userclass = new TreeMap<>();
53  env = new Environment(this, defaultWindowName, lockProperties);
54  nodeList = new LinkedList<>();
55  tokenList = new LinkedList<>();
56  }
57 
58  public Program(String source, ParserFactory parserFactory, String defaultWindowName, boolean lockProperties) {
59  this.defaultWindowName = defaultWindowName;
60  this.lockProperties = lockProperties;
61  this.parserFactory = parserFactory;
62  this.machine = new Machine();
63  this.program = new Sequence();
64  this.prettyPrinter = new PrettyPrinter(source);
65  this.source = source;
66  sub = new LinkedList<>();
67  userclass = new TreeMap<>();
68  env = new Environment(this, defaultWindowName, lockProperties);
69  nodeList = new LinkedList<>();
70  tokenList = new LinkedList<>();
71  }
72 
73  @Override
74  public synchronized void parse(String path) throws TranslationException {
75  parser = parserFactory.createParser(source);
76  parser.parse(this, path);
77  }
78 
79  public void add(Sequence s) {
80  program.append(s);
81  }
82 
83  public void add(SubRoutine s) {
84  sub.add(s);
85  }
86 
87  public void add(UserClass u) {
88  userclass.put(u.getName(), u);
89  }
90 
91  public void addNode(MarkedNode node) {
92  nodeList.add(node);
93  }
94 
95  public void addToken(SourceToken sourceToken) {
96  tokenList.add(sourceToken);
97  }
98 
99  public LinkedList<MarkedNode> getNodeList() {
100  return nodeList;
101  }
102 
103  @Override
104  public LinkedList<InfoToken> getTokenList() {
105  return tokenList;
106  }
107 
108  @Override
110  return program;
111  }
112 
113  public void merge(Program subprogram, Marker marker) {
114  // override all debugging markers
115  for (MarkedNode n : subprogram.nodeList) {
116  n.setMarker(marker);
117  }
118  this.program.append(subprogram.program);
119  this.sub.addAll(subprogram.sub);
120  this.userclass.putAll(subprogram.userclass);
121  this.nodeList.addAll(subprogram.nodeList);
122  }
123 
124  @Override
125  public LinkedList<ProgramUnit> getSubPrograms() {
126  LinkedList<ProgramUnit> temp = new LinkedList<>();
127  sub.forEach(s -> temp.add(s));
128  return temp;
129  }
130 
136  public void compile(Machine m) throws Exception {
137  env.resetAll();
138  // first scan, resolve types
139  for (UserClass uc : userclass.values()) { // prepare user types
140  uc.bind(env);
141  }
142  for (UserClass uc : userclass.values()) { // check for storage cycles
143  uc.checkCyclicStorage();
144  }
145 
146  for (SubRoutine s : sub) { // register all sub routines
147  s.registerSub(env);
148  }
149 
150  for (UserClass uc : userclass.values()) { // finish user types
151  uc.resolveNamesAndTypes(env);
152  }
153 
154  program.resolveNamesAndTypes(null, env);
155 
156  env.storeVariables();
157  for (SubRoutine s : sub) {
158  if (s.getGlobalAccess()) {
159  env.restoreVariables();
160  } else {
161  env.resetVariables();
162  }
163  s.resolveNamesAndTypes(null, env);
164  }
165 
166  // second scan produce commands
167  for (UserClass uc : userclass.values()) { // compile user types
168  uc.compile();
169  }
170  ArrayList<Command> ops = new ArrayList<>();
171  if (env.getAutoWindow()) {
173  }
174  program.compile(ops, env.getAutoWindow());
175  ops.add(new DebugPoint());
176  m.setProgram(ops);
177  for (SubRoutine s : sub) {
178  ops = new ArrayList<>();
179  // automatic add to window only works with user function that have
180  // global access to the window object
181  // methods can, procedures cannot.
182  s.compile(ops, s.getGlobalAccess() && env.getAutoWindow());
183  m.addUserFunction(Signatures.createUserFunctionSignature(s.getLabel(), s.getParameterTypes()), new MProcedure(ops, s.getGlobalAccess()));
184  }
185  }
186 
187  @Override
188  public LinkedList<ErrorInformation> getErrors() {
189  return env.getErrors();
190  }
191 
192  @Override
193  public AutoCompleteType seekType(int position) {
194  Type type;
195  type = seekTypeSemantical(position);
196  if (type == null || type.isUnknown() || type.isVoid()) {
197  type = useBestGuess(position);
198  }
199  return type;
200  }
201 
202  private Type seekTypeSemantical(int position) {
203  MarkedNode target = null;
204  for (MarkedNode node : nodeList) {
205  if (node.getMarker().getEndPosition() < position) {
206  if (node instanceof Expression && node.getMarker().getEndPosition() == position - 1) {
207  target = node;
208  break;
209  }
210  } else {
211  break;
212  }
213  }
214  if (target == null) {
215  return Type.getUnknown();
216  } else {
217  return target.getType();
218  }
219  }
220 
221  private Type useBestGuess(int position) {
222  int start = 0;
223  for (int i = Math.min(position, source.length()); i-- > 0;) {
224  if (Character.isWhitespace(source.charAt(i))) {
225  start = i + 1;
226  break;
227  }
228  }
229  String name = source.substring(start, position).trim();
230  if (guessTable.containsKey(name)) {
231  return guessTable.get(name);
232  } else {
233  return Type.getUnknown();
234  }
235  }
236 
237  public static void addGuess(String name, Type type) {
238  if (type != null && !type.isUnknown() && !type.isVoid()) {
239  guessTable.put(name, type);
240  }
241  }
242 
243  @Override
244  public String getSource() {
245  return source;
246  }
247 
248  @Override
249  public synchronized int getLine(int pos) {
250  return parser.getLine(pos);
251  }
252 
253  @Override
254  public String toString() {
255  StringBuilder res = new StringBuilder();
256  res.append("program\n");
257  res.append(program);
258  res.append("endprogram\n");
259  for (SubRoutine s : sub) {
260  res.append(s);
261  }
262  for (UserClass uc : userclass.values()) {
263  res.append(uc);
264  }
265  res.append(env);
266  return res.toString();
267  }
268 
269  public void prettyPrinterNewline(int position, int level) {
270  prettyPrinter.newline(position, level);
271  }
272 
273  @Override
274  public String prettyPrint() {
275  return prettyPrinter.prettyPrint();
276  }
277 
278  @Override
279  public void compile() throws TranslationException {
280  try {
281  machine.reinit();
282  compile(machine);
283  } catch (Exception e) {
284  throw new TranslationException(new CompilerError("Compile.Error", e.getLocalizedMessage()));
285  }
286  }
287 
288  @Override
290  return machine;
291  }
292 
293  @Override
294  public LinkedList<AutoCompleteInformation> getClassAutoCompletes() {
295  LinkedList<AutoCompleteInformation> classInfos = new LinkedList<>();
296  classInfos.addAll(SystemType.getClassType().getAutoCompletes());
297  for (UserClass uc : userclass.values()) {
298  classInfos.add(uc.getAutoComplete());
299  }
300  return classInfos;
301  }
302  @Override
303  public Type getTypeByName(String name) {
305  if (t == null || t.isUnknown()) {
306  UserClass uc = userclass.getOrDefault(name.toLowerCase(), null);
307  if (uc != null) {
308  t = uc.getType();
309  } else {
310  uc = new UserClass(name);
311  userclass.put(name.toLowerCase(), uc);
312  t = uc.getType();
313  }
314  }
315  return t;
316  }
317  public UserClass createUserClass(String name) {
318  SystemType st = SystemType.getInstanceByName(name.toLowerCase());
319  if (st != null && !st.isUnknown()) {
320  throw new DoubleClassDeclarationException(name);
321  }
322  UserClass uc = userclass.getOrDefault(name.toLowerCase(), null);
323  if (uc == null) {
324  uc = new UserClass(name);
325  userclass.put(name.toLowerCase(), uc);
326  }
327  uc.define();
328  return uc;
329  }
330 }
LinkedList< ErrorInformation > getErrors()
synchronized int getLine(int pos)
Definition: Program.java:249
AutoCompleteType seekType(int position)
Definition: Program.java:193
synchronized void parse(String path)
Definition: Program.java:74
void merge(Program subprogram, Marker marker)
Definition: Program.java:113
static void addGuess(String name, Type type)
Definition: Program.java:237
LinkedList< AutoCompleteInformation > getClassAutoCompletes()
Definition: Program.java:294
Program(String source, ParserFactory parserFactory, String defaultWindowName, boolean lockProperties)
Definition: Program.java:58
UserClass createUserClass(String name)
Definition: Program.java:317
LinkedList< ErrorInformation > getErrors()
Definition: Program.java:188
void addNode(MarkedNode node)
Definition: Program.java:91
Program(ParserFactory parserFactory, String defaultWindowName, boolean lockProperties)
Definition: Program.java:43
LinkedList< InfoToken > getTokenList()
Definition: Program.java:104
LinkedList< MarkedNode > getNodeList()
Definition: Program.java:99
LinkedList< ProgramUnit > getSubPrograms()
Definition: Program.java:125
void prettyPrinterNewline(int position, int level)
Definition: Program.java:269
Type getTypeByName(String name)
Definition: Program.java:303
void addToken(SourceToken sourceToken)
Definition: Program.java:95
void resolveNamesAndTypes(Expression with, Environment env)
Definition: Sequence.java:67
void compile(ArrayList< Command > ops, boolean autoWindow)
Definition: Sequence.java:53
static String createUserFunctionSignature(String name, Type[] parameters)
Definition: Signatures.java:9
static SystemType getInstanceByName(String name)
LinkedList< AutoCompleteInformation > getAutoCompletes()
Definition: Type.java:184
void newline(int position, int level)
void parse(Program program, String path)
BasicParser createParser(String source)
Impressum