ScriptStack 1.0.5
Loading...
Searching...
No Matches
ScriptStack.Runtime.Script Class Reference

Internal representation of a text file (source code) which can be passed to the Interpreter to execute it. More...

Public Member Functions

 Script (Manager manager, string scriptName)
 Script (Manager manager, string scriptName, bool binary)
void CompileBinary (string fileName)
void CompileJSON (string fileName)
bool EntryPoint ()

Properties

Manager Manager [get]
string Name [get]
ReadOnlyCollection< String > SourceLines [get]
string Source [get]
Executable Executable [get]
Memory ScriptMemory [get]
ScriptStack.Collections.ReadOnlyDictionary< String, FunctionFunctions [get]
Function MainFunction [get]

Private Member Functions

void Scan (string scriptName)

Static Private Member Functions

static object ConvertLexeme (SerializableToken st)
static object ConvertLexeme (TokenType type, string lexemeStr)

Private Attributes

Manager manager
String scriptName
List< String > sourceCode
Executable executable

Detailed Description

Internal representation of a text file (source code) which can be passed to the Interpreter to execute it.

Definition at line 17 of file Script.cs.

Constructor & Destructor Documentation

◆ Script() [1/2]

ScriptStack.Runtime.Script.Script ( Manager manager,
string scriptName )

Definition at line 219 of file Script.cs.

220 {
221
222 this.manager = manager;
223
224 this.scriptName = scriptName;
225
226 try
227 {
228
229 Scan(scriptName);
230
231 //Lexer lexer = new Lexer(sourceCode);
232 Lexer lexer = manager.LexerFactory(sourceCode);
233
234 List<Token> tokenStream = lexer.GetTokens();
235
236 Parser parser = new Parser(this, tokenStream);
237
238 parser.DebugMode = this.manager.Debug;
239
240 executable = parser.Parse();
241
242 if (this.manager.Optimize)
243 {
244
245 Optimizer optimizer = new Optimizer(executable);
246
247 optimizer.OptimizerInfo = false;
248
249 optimizer.Optimize();
250
251 }
252
253
254 }
255 catch (Exception exception)
256 {
257 throw new ScriptStackException("Fehler in '" + scriptName + "'.", exception);
258 }
259
260 }
List< Token > GetTokens()
Definition Lexer.cs:177
Executable Parse()
Parse the token stream into an executable.
Definition Parser.cs:3355

References ScriptStack.Manager.Debug, executable, ScriptStack.Compiler.Lexer.GetTokens(), Manager, manager, ScriptStack.Manager.Optimize, ScriptStack.Compiler.Parser.Parse(), Scan(), scriptName, and sourceCode.

◆ Script() [2/2]

ScriptStack.Runtime.Script.Script ( Manager manager,
string scriptName,
bool binary )

Definition at line 262 of file Script.cs.

263 {
264
265 this.manager = manager;
266
267 this.scriptName = scriptName;
268
269 try
270 {
271
272 List<Token> tokenStream = null;
273 if (binary == true)
274 {
275 tokenStream = new List<Token>();
276 using (var fs = new FileStream(scriptName, FileMode.Open, FileAccess.Read))
277 using (var br = new BinaryReader(fs))
278 {
279 int count = br.ReadInt32();
280
281 for (int i = 0; i < count; i++)
282 {
283 var typeInt = br.ReadInt32();
284 var lexemeStr = br.ReadString();
285 var line = br.ReadInt32();
286 var column = br.ReadInt32();
287 var text = ""; // br.ReadString();
288
289 TokenType type = (TokenType)typeInt;
290 object lexeme = ConvertLexeme(type, lexemeStr);
291
292 tokenStream.Add(new Token(type, lexeme, line, column, text));
293 }
294 }
295 }
296 else
297 {
298 string json = File.ReadAllText(scriptName, Encoding.UTF8);
299
300 var serializableTokens = JsonSerializer.Deserialize<List<SerializableToken>>(json);
301
302 // Falls du wieder echte Token-Objekte brauchst:
303 tokenStream = serializableTokens
304 .Select(st => new Token(
305 st.Type,
306 ConvertLexeme(st), // (st.Lexeme) oder hier wieder in int/float/etc. umwandeln, wenn nötig
307 st.Line,
308 st.Column,
309 st.Text))
310 .ToList();
311 }
312
313 Parser parser = new Parser(this, tokenStream);
314
315 parser.DebugMode = this.manager.Debug;
316
317 executable = parser.Parse();
318
319
320 if (this.manager.Optimize)
321 {
322
323 Optimizer optimizer = new Optimizer(executable);
324
325 optimizer.OptimizerInfo = false;
326
327 optimizer.Optimize();
328
329 }
330
331
332 }
333 catch (Exception exception)
334 {
335 throw new ScriptStackException("Fehler in '" + scriptName + "'.", exception);
336 }
337
338 }
TokenType
Known types of Token.
Definition Token.cs:12

References ConvertLexeme(), ScriptStack.Manager.Debug, executable, Manager, manager, ScriptStack.Manager.Optimize, ScriptStack.Compiler.Parser.Parse(), and scriptName.

Member Function Documentation

◆ CompileBinary()

void ScriptStack.Runtime.Script.CompileBinary ( string fileName)

Definition at line 340 of file Script.cs.

341 {
342
343 try
344 {
345
346 Scan(scriptName);
347
348 Lexer lexer = new Lexer(sourceCode);
349
350 List<Token> tokenStream = lexer.GetTokens();
351
352 using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
353 using (var bw = new BinaryWriter(fs))
354 {
355 // Anzahl Tokens zuerst
356 bw.Write(tokenStream.Count);
357
358 foreach (var t in tokenStream)
359 {
360 bw.Write((int)t.Type); // Enum als int
361 bw.Write(t.Lexeme?.ToString() ?? ""); // als String
362 bw.Write(t.Line);
363 bw.Write(t.Column);
364 //bw.Write(t.Text ?? "");
365 }
366 }
367
368 }
369 catch (Exception exception)
370 {
371 throw new ScriptStackException("Fehler in '" + scriptName + "'.", exception);
372 }
373 }

References ScriptStack.Compiler.Lexer.GetTokens(), Scan(), scriptName, and sourceCode.

◆ CompileJSON()

void ScriptStack.Runtime.Script.CompileJSON ( string fileName)

Definition at line 375 of file Script.cs.

376 {
377
378 try
379 {
380
381 Scan(scriptName);
382
383 Lexer lexer = new Lexer(sourceCode);
384
385 List<Token> tokenStream = lexer.GetTokens();
386
387 var serializableTokens = tokenStream.Select(t => new SerializableToken
388 {
389 Type = t.Type,
390 Lexeme = t.Lexeme?.ToString(),
391 Line = t.Line,
392 Column = t.Column,
393 Text = t.Text
394 }).ToList();
395
396 var options = new JsonSerializerOptions
397 {
398 WriteIndented = true // für schön formatiertes JSON
399 };
400
401 string json = JsonSerializer.Serialize(serializableTokens, options);
402
403 // In Datei schreiben
404 File.WriteAllText(fileName, json, Encoding.UTF8);
405
406 }
407 catch (Exception exception)
408 {
409 throw new ScriptStackException("Fehler in '" + scriptName + "'.", exception);
410 }
411 }

References ScriptStack.Compiler.Lexer.GetTokens(), Scan(), scriptName, and sourceCode.

◆ ConvertLexeme() [1/2]

object ScriptStack.Runtime.Script.ConvertLexeme ( SerializableToken st)
staticprivate

Definition at line 102 of file Script.cs.

103 {
104 if (st.Lexeme == null)
105 return null;
106
107 // Je nach TokenType anders parsen
108 switch (st.Type)
109 {
110 case TokenType.Integer:
111 // z.B. "42" -> 42
112 return int.Parse(st.Lexeme, CultureInfo.InvariantCulture);
113
114 case TokenType.Float:
115 // z.B. "3.14" -> 3.14f
116 return float.Parse(st.Lexeme, CultureInfo.InvariantCulture);
117
118 case TokenType.Double:
119 // z.B. "3.14159" -> 3.14159d
120 return double.Parse(st.Lexeme, CultureInfo.InvariantCulture);
121
122 case TokenType.Boolean:
123 // "true" / "false"
124 return bool.Parse(st.Lexeme);
125
126 case TokenType.Char:
127 // hängt davon ab, wie dein Lexer das Lexeme speichert
128 // Beispiel 1: nur das Zeichen selbst: "a"
129 if (st.Lexeme.Length == 1)
130 return st.Lexeme[0];
131
132 // Beispiel 2: inklusive Hochkommas: "'a'"
133 if (st.Lexeme.Length >= 3 &&
134 st.Lexeme[0] == '\'' &&
135 st.Lexeme[^1] == '\'')
136 {
137 return st.Lexeme[1];
138 }
139
140 throw new FormatException($"Ungültiges Char-Lexeme: '{st.Lexeme}'");
141
142 case TokenType.Null:
143 // für 'null' kannst du einfach null zurückgeben
144 return null;
145
146 case TokenType.String:
147 // hier kannst du entscheiden:
148 // - komplette Literal-Syntax behalten ("\"Hallo\"")
149 // - oder die Anführungszeichen entfernen, wenn dein Lexer sie drin hat
150 // Beispiel: Anführungszeichen entfernen:
151 if (st.Lexeme.Length >= 2 &&
152 st.Lexeme[0] == '"' &&
153 st.Lexeme[^1] == '"')
154 {
155 return st.Lexeme.Substring(1, st.Lexeme.Length - 2);
156 }
157 return st.Lexeme;
158
159 default:
160 // für alles andere reicht der String
161 return st.Lexeme;
162 }
163 }

References ScriptStack.Compiler.SerializableToken.Lexeme, and ScriptStack.Compiler.SerializableToken.Type.

Referenced by Script().

◆ ConvertLexeme() [2/2]

object ScriptStack.Runtime.Script.ConvertLexeme ( TokenType type,
string lexemeStr )
staticprivate

Definition at line 165 of file Script.cs.

166 {
167 // Falls du für Null-Tokens z.B. ein leeres Lexeme speicherst:
168 if (type == TokenType.Null)
169 return null;
170
171 if (lexemeStr == null)
172 return null;
173
174 switch (type)
175 {
176 case TokenType.Integer:
177 return int.Parse(lexemeStr, CultureInfo.InvariantCulture);
178
179 case TokenType.Float:
180 return float.Parse(lexemeStr, CultureInfo.InvariantCulture);
181
182 case TokenType.Double:
183 return double.Parse(lexemeStr, CultureInfo.InvariantCulture);
184
185 case TokenType.Boolean:
186 return bool.Parse(lexemeStr);
187
188 case TokenType.Char:
189 // Variante 1: nur das Zeichen selbst gespeichert, z.B. "a"
190 if (lexemeStr.Length == 1)
191 return lexemeStr[0];
192
193 // Variante 2: inkl. Hochkommas, z.B. "'a'"
194 if (lexemeStr.Length >= 3 &&
195 lexemeStr[0] == '\'' &&
196 lexemeStr[^1] == '\'')
197 {
198 return lexemeStr[1];
199 }
200
201 throw new FormatException($"Ungültiges Char-Lexeme: '{lexemeStr}'");
202
203 case TokenType.String:
204 // Wenn dein Lexer die Anführungszeichen mit speichert ("\"Hallo\"")
205 if (lexemeStr.Length >= 2 &&
206 lexemeStr[0] == '"' &&
207 lexemeStr[^1] == '"')
208 {
209 return lexemeStr.Substring(1, lexemeStr.Length - 2);
210 }
211 return lexemeStr;
212
213 default:
214 // Für alles andere reicht der String
215 return lexemeStr;
216 }
217 }

◆ EntryPoint()

bool ScriptStack.Runtime.Script.EntryPoint ( )

Definition at line 413 of file Script.cs.

414 {
415 return executable.FunctionExists("main");
416 }

References executable.

◆ Scan()

void ScriptStack.Runtime.Script.Scan ( string scriptName)
private

Definition at line 31 of file Script.cs.

32 {
33
34 Scanner scanner = manager.Scanner;
35 sourceCode = scanner.Scan(scriptName);
36 sourceCode.Add(" ");
37
38 Dictionary<string, bool> included = new Dictionary<string, bool>();
39
40 for (int i = 0; i < sourceCode.Count; i++)
41 {
42
43 string line = sourceCode[i];
44
45 Lexer lexer = new Lexer(new List<string> { line });
46
47 List<Token> tokenStream = null;
48
49 try
50 {
51 tokenStream = lexer.GetTokens();
52 }
53 catch (Exception)
54 {
55 continue;
56 }
57
58 if (tokenStream.Count == 0)
59 continue;
60
61 if (tokenStream[0].Type != TokenType.Include)
62 continue;
63
64 if (tokenStream.Count < 2)
65 throw new ParserException("Include Statement ohne Pfadangabe.");
66
67 if (tokenStream[1].Type != TokenType.String)
68 throw new ParserException("Nach einem 'include' Befehl wird ein String (Pfad) erwartet.");
69
70 if (tokenStream.Count < 3)
71 throw new ParserException("Semicolon ';' am Ende eines 'include' Statement erwartet.");
72
73 if (tokenStream[2].Type != TokenType.SemiColon)
74 throw new ParserException("Semicolon ';' am Ende eines 'include' Statement erwartet.");
75
76 if (tokenStream.Count > 3)
77 throw new ParserException("Es wird nichts nach dem Semicolon ';' am Ende eines 'include' Statement erwartet.");
78
79 string include = (string)tokenStream[1].Lexeme;
80
81 sourceCode.RemoveAt(i);
82
83 if (included.ContainsKey(include))
84 continue;
85
86 /* and place the source where the original include statement was.. */
87 sourceCode.InsertRange(i, scanner.Scan(include));
88
89 /* set the current script as already included */
90 included[include] = true;
91
92 --i;
93
94 }
95
96 }
List< String > Scan(String strResourceName)

References ScriptStack.Compiler.Lexer.GetTokens(), manager, ScriptStack.Compiler.Scanner.Scan(), scriptName, and sourceCode.

Referenced by CompileBinary(), CompileJSON(), and Script().

Member Data Documentation

◆ executable

Executable ScriptStack.Runtime.Script.executable
private

Definition at line 25 of file Script.cs.

Referenced by EntryPoint(), Script(), and Script().

◆ manager

Manager ScriptStack.Runtime.Script.manager
private

Definition at line 22 of file Script.cs.

Referenced by Scan(), Script(), and Script().

◆ scriptName

String ScriptStack.Runtime.Script.scriptName
private

Definition at line 23 of file Script.cs.

Referenced by CompileBinary(), CompileJSON(), Scan(), Script(), and Script().

◆ sourceCode

List<String> ScriptStack.Runtime.Script.sourceCode
private

Definition at line 24 of file Script.cs.

Referenced by CompileBinary(), CompileJSON(), Scan(), and Script().

Property Documentation

◆ Executable

Executable ScriptStack.Runtime.Script.Executable
get

Definition at line 451 of file Script.cs.

452 {
453 get { return executable; }
454 }

◆ Functions

ScriptStack.Collections.ReadOnlyDictionary<String, Function> ScriptStack.Runtime.Script.Functions
get

Definition at line 461 of file Script.cs.

462 {
463 get
464 {
465 return new ScriptStack.Collections.ReadOnlyDictionary<String,Function>(executable.Functions);
466 }
467 }

◆ MainFunction

Function ScriptStack.Runtime.Script.MainFunction
get

Definition at line 469 of file Script.cs.

470 {
471 get { return executable.MainFunction; }
472 }

◆ Manager

Manager ScriptStack.Runtime.Script.Manager
get

Definition at line 422 of file Script.cs.

423 {
424 get { return manager; }
425 }

Referenced by Script(), and Script().

◆ Name

string ScriptStack.Runtime.Script.Name
get

Definition at line 427 of file Script.cs.

428 {
429 get { return scriptName; }
430 }

◆ ScriptMemory

Memory ScriptStack.Runtime.Script.ScriptMemory
get

Definition at line 456 of file Script.cs.

457 {
458 get { return executable.ScriptMemory; }
459 }

◆ Source

string ScriptStack.Runtime.Script.Source
get

Definition at line 437 of file Script.cs.

438 {
439 get
440 {
441 StringBuilder sb = new StringBuilder();
442 foreach (string line in sourceCode)
443 {
444 sb.Append(line);
445 sb.Append("\r\n");
446 }
447 return sb.ToString();
448 }
449 }

◆ SourceLines

ReadOnlyCollection<String> ScriptStack.Runtime.Script.SourceLines
get

Definition at line 432 of file Script.cs.

433 {
434 get { return sourceCode.AsReadOnly(); }
435 }

The documentation for this class was generated from the following file: