From af93af0c8d0e8da7ed0bb4236853b75fd52b99d4 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Tue, 2 Aug 2022 19:21:53 +0200 Subject: [PATCH 01/13] Intermediate commit --- Parser.cs | 13 +++++++++++-- Program.cs | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Parser.cs b/Parser.cs index e59dac6..5562918 100644 --- a/Parser.cs +++ b/Parser.cs @@ -147,7 +147,7 @@ private static Token[] BracketsParse(Token[] line, int i, string[] lines, ref in private static MultilineStatementOperator CurlyBracketsParse(Token[] line, string[] lines, ref int i, Token parent, int depth) { // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree List tokens = new List(); - int initialIndex = ++i; // immediately increment i so that this function doesn't try to parse itself, but instead the next line (also fixes the error message) + int initialIndex = i; int numBrackets = 1; for (; i < lines.Length; i++) { CheckedString[] lexedLine = Lexer.Lex(lines[i], i + 1); @@ -159,6 +159,15 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin Token[] tokenizedLine = Tokenizer.Tokenize(lexedLine); int before = i; + + if (i == initialIndex) { + for (int j = 0; j < tokenizedLine.Length; j++) { + if (tokenizedLine[j] is MultilineStatementOperator) { + tokenizedLine = new ArraySegment(tokenizedLine, j + 1, tokenizedLine.Length - (j + 1)).ToArray(); + break; + } + } + } tokens.Add(Parse(tokenizedLine, GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, depth + 1)); if (i != before) @@ -181,7 +190,7 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin FullBreak: if (i >= lines.Length) - throw new FormatException("no matched bracket for bracket on line " + initialIndex); + throw new FormatException("no matched bracket for bracket on line " + (initialIndex + 1)); ((MultilineStatementOperator) line[^1]).Children = tokens.ToArray(); diff --git a/Program.cs b/Program.cs index fa997c0..7915d9b 100644 --- a/Program.cs +++ b/Program.cs @@ -135,8 +135,8 @@ public static void Main(string[] args) { Token tree = Parser.Parse(tokenizedLine, Parser.GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, 0); - // Console.WriteLine(tree.ToString(0)); - tree.Evaluate(new List> {vars}); + Console.WriteLine(tree.ToString(0)); + // tree.Evaluate(new List> {vars}); } } } From 67bb5ee357ce80919c0066ea86d51029094b2320 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Tue, 2 Aug 2022 19:47:55 +0200 Subject: [PATCH 02/13] Made existing curly bracket parsing less strict --- Parser.cs | 33 ++++++++++++++++++++------------- Program.cs | 4 ++-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Parser.cs b/Parser.cs index 5562918..9f55e84 100644 --- a/Parser.cs +++ b/Parser.cs @@ -140,15 +140,14 @@ private static Token[] BracketsParse(Token[] line, int i, string[] lines, ref in return properArguments.ToArray(); } - - /** - * Note that this is a bad implementation with too strict constraints, but for now, only functionality is important - */ + private static MultilineStatementOperator CurlyBracketsParse(Token[] line, string[] lines, ref int i, Token parent, int depth) { // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree List tokens = new List(); int initialIndex = i; int numBrackets = 1; + bool isFirstBracketFound = false; + MultilineStatementOperator firstFoundBracket = null!; for (; i < lines.Length; i++) { CheckedString[] lexedLine = Lexer.Lex(lines[i], i + 1); @@ -159,24 +158,32 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin Token[] tokenizedLine = Tokenizer.Tokenize(lexedLine); int before = i; - - if (i == initialIndex) { + bool doContinue = false; + if (!isFirstBracketFound) { + doContinue = true; for (int j = 0; j < tokenizedLine.Length; j++) { - if (tokenizedLine[j] is MultilineStatementOperator) { + if (tokenizedLine[j] is MultilineStatementOperator mso) { + isFirstBracketFound = true; + firstFoundBracket = mso; tokenizedLine = new ArraySegment(tokenizedLine, j + 1, tokenizedLine.Length - (j + 1)).ToArray(); + doContinue = tokenizedLine.Length == 0; // Happens if first line of declaration ends with an opening curly bracket break; } } } - tokens.Add(Parse(tokenizedLine, GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, depth + 1)); + if (doContinue) // Happens for before mentioned case and if no curly bracket is found at all + continue; + + tokens.Add(Parse(tokenizedLine, GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, depth + 1)); + if (i != before) continue; - foreach (CheckedString cs in lexedLine) { - if (cs.Str == "}") + foreach (Token t in tokenizedLine) { + if (t.Str == "}") numBrackets--; - else if (cs.Str == "{") + else if (t.Str == "{") numBrackets++; if (numBrackets == 0) { @@ -192,9 +199,9 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin if (i >= lines.Length) throw new FormatException("no matched bracket for bracket on line " + (initialIndex + 1)); - ((MultilineStatementOperator) line[^1]).Children = tokens.ToArray(); + firstFoundBracket.Children = tokens.ToArray(); - return (MultilineStatementOperator) line[^1]; + return firstFoundBracket; } public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, int depth) { diff --git a/Program.cs b/Program.cs index 7915d9b..fa997c0 100644 --- a/Program.cs +++ b/Program.cs @@ -135,8 +135,8 @@ public static void Main(string[] args) { Token tree = Parser.Parse(tokenizedLine, Parser.GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, 0); - Console.WriteLine(tree.ToString(0)); - // tree.Evaluate(new List> {vars}); + // Console.WriteLine(tree.ToString(0)); + tree.Evaluate(new List> {vars}); } } } From 5dceda03ec7fe94fbd2c18fdf43ae11e66875575 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Fri, 5 Aug 2022 00:24:37 +0200 Subject: [PATCH 03/13] Very basic curly bracket parsing outside statements --- Parser.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Parser.cs b/Parser.cs index 9f55e84..6211ec1 100644 --- a/Parser.cs +++ b/Parser.cs @@ -12,7 +12,7 @@ namespace Interpreter; public class Parser { public static int GetTopElementIndex(Token[] line, int startIndex, bool isRightBound) { - if (line[startIndex] is BinaryStatement) + if (line[startIndex] is BinaryStatement or MultilineStatementOperator) return startIndex; int highestPriorityNum = -1; @@ -323,6 +323,14 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i unStat.Child = po; break; } + case MultilineStatementOperator mso: { + if (mso.Str == "}") + break; + + // TODO: fix this weird property copying and add this to statement parsing and also fix parsing for simple objects + mso.Children = CurlyBracketsParse(line, lines, ref lineNo, mso, depth + 1).Children; + break; + } } t.Line = line[i].Line; From b35015604394011867eba53af725f2a7543eb6cb Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Tue, 9 Aug 2022 23:57:17 +0200 Subject: [PATCH 04/13] Prepared for simple object parsing --- Parser.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Parser.cs b/Parser.cs index 6211ec1..91fb9c5 100644 --- a/Parser.cs +++ b/Parser.cs @@ -141,7 +141,7 @@ private static Token[] BracketsParse(Token[] line, int i, string[] lines, ref in return properArguments.ToArray(); } - private static MultilineStatementOperator CurlyBracketsParse(Token[] line, string[] lines, ref int i, Token parent, int depth) { + private static MultilineStatementOperator CurlyBracketsParse(Token[] line, string[] lines, ref int i, Token parent, bool isObject, int depth) { // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree List tokens = new List(); int initialIndex = i; @@ -301,14 +301,14 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i j++; } while (numBrackets != 0); - statement.Right = CurlyBracketsParse(line, lines, ref lineNo, statement, depth + 1); + statement.Right = CurlyBracketsParse(line, lines, ref lineNo, statement, false, depth + 1); break; } case ElseStatement or ClassStatement: { if (t is ClassStatement classStat) classStat.Name = line[i + 1].Str; - Token child = CurlyBracketsParse(line, lines, ref lineNo, t, depth + 1); + Token child = CurlyBracketsParse(line, lines, ref lineNo, t, false, depth + 1); if (child is not MultilineStatementOperator mso) throw new FormatException("statement argument on line " + child.Line + " needs curly brackets"); @@ -328,7 +328,7 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i break; // TODO: fix this weird property copying and add this to statement parsing and also fix parsing for simple objects - mso.Children = CurlyBracketsParse(line, lines, ref lineNo, mso, depth + 1).Children; + mso.Children = CurlyBracketsParse(line, lines, ref lineNo, mso, true, depth + 1).Children; break; } } From 9c17902c33e28a55482b894c903002b304828e9f Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Wed, 10 Aug 2022 22:56:02 +0200 Subject: [PATCH 05/13] Proper simple object parsing preparation --- Parser.cs | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/Parser.cs b/Parser.cs index 91fb9c5..24cec0b 100644 --- a/Parser.cs +++ b/Parser.cs @@ -141,7 +141,7 @@ private static Token[] BracketsParse(Token[] line, int i, string[] lines, ref in return properArguments.ToArray(); } - private static MultilineStatementOperator CurlyBracketsParse(Token[] line, string[] lines, ref int i, Token parent, bool isObject, int depth) { + private static MultilineStatementOperator CurlyBracketsParse(Token[] line, string[] lines, ref int i, Token parent, int depth) { // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree List tokens = new List(); int initialIndex = i; @@ -203,6 +203,66 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin return firstFoundBracket; } + + private static MultilineStatementOperator SimpleObjectParse(Token[] line, string[] lines, ref int i, int depth) { + // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree + List tokens = new List(); + int initialIndex = i; + int numBrackets = 1; + bool isFirstBracketFound = false; + MultilineStatementOperator firstFoundBracket = null!; + for (; i < lines.Length; i++) { + // TODO: Match : + CheckedString[] lexedLine = Lexer.Lex(lines[i], i + 1); + + lexedLine = CheckComment(lexedLine); + if (lexedLine.Length == 0) + continue; + + Token[] tokenizedLine = Tokenizer.Tokenize(lexedLine); + + int before = i; + bool doContinue = false; + if (!isFirstBracketFound) { + doContinue = true; + for (int j = 0; j < tokenizedLine.Length; j++) { + if (tokenizedLine[j] is MultilineStatementOperator mso) { + isFirstBracketFound = true; + firstFoundBracket = mso; + tokenizedLine = new ArraySegment(tokenizedLine, j + 1, tokenizedLine.Length - (j + 1)).ToArray(); + doContinue = tokenizedLine.Length == 0; // Happens if first line of declaration ends with an opening curly bracket + break; + } + } + } + + if (doContinue) // Happens for before mentioned case and if no curly bracket is found at all + continue; + + tokens.Add(Parse(tokenizedLine, GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, depth + 1)); + + if (i != before) + continue; + + foreach (Token t in tokenizedLine) { + if (t.Str == "}") + numBrackets--; + else if (t.Str == "{") + numBrackets++; + + if (numBrackets == 0) + goto FullBreak; + } + } + FullBreak: + + if (i >= lines.Length) + throw new FormatException("no matched bracket for bracket on line " + (initialIndex + 1)); + + firstFoundBracket.Children = tokens.ToArray(); + + return firstFoundBracket; + } public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, int depth) { Token t = line[i]; @@ -301,14 +361,14 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i j++; } while (numBrackets != 0); - statement.Right = CurlyBracketsParse(line, lines, ref lineNo, statement, false, depth + 1); + statement.Right = CurlyBracketsParse(line, lines, ref lineNo, statement, depth + 1); break; } case ElseStatement or ClassStatement: { if (t is ClassStatement classStat) classStat.Name = line[i + 1].Str; - Token child = CurlyBracketsParse(line, lines, ref lineNo, t, false, depth + 1); + Token child = CurlyBracketsParse(line, lines, ref lineNo, t, depth + 1); if (child is not MultilineStatementOperator mso) throw new FormatException("statement argument on line " + child.Line + " needs curly brackets"); @@ -328,7 +388,7 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i break; // TODO: fix this weird property copying and add this to statement parsing and also fix parsing for simple objects - mso.Children = CurlyBracketsParse(line, lines, ref lineNo, mso, true, depth + 1).Children; + mso.Children = SimpleObjectParse(line, lines, ref lineNo, depth + 1).Children; break; } } From 80f939fa6ab2903e84705bd915203377f91919ac Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Thu, 11 Aug 2022 19:09:03 +0200 Subject: [PATCH 06/13] Proper selection in parsing simple objects --- Parser.cs | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/Parser.cs b/Parser.cs index 24cec0b..ce475e6 100644 --- a/Parser.cs +++ b/Parser.cs @@ -157,6 +157,7 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin Token[] tokenizedLine = Tokenizer.Tokenize(lexedLine); + // Find first curly bracket int before = i; bool doContinue = false; if (!isFirstBracketFound) { @@ -208,9 +209,11 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree List tokens = new List(); int initialIndex = i; - int numBrackets = 1; + int numBrackets = 0; bool isFirstBracketFound = false; MultilineStatementOperator firstFoundBracket = null!; + List properLines = new List(); + List subLine = new List(); for (; i < lines.Length; i++) { // TODO: Match : CheckedString[] lexedLine = Lexer.Lex(lines[i], i + 1); @@ -220,7 +223,38 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string continue; Token[] tokenizedLine = Tokenizer.Tokenize(lexedLine); + + foreach (Token t in tokenizedLine) { + if (t.Str == "}") + numBrackets--; + else if (t.Str == "{") { + if (!isFirstBracketFound) { + isFirstBracketFound = true; + numBrackets++; + continue; + } + numBrackets++; + } + if (!isFirstBracketFound) + continue; + + if (t is CommaSeparator && numBrackets == 1) { + properLines.Add(subLine.ToArray()); + subLine = new List(); + continue; + } + + if (numBrackets == 0) { + properLines.Add(subLine.ToArray()); + goto FullBreak; + } + + subLine.Add(t); + } + continue; + + // Find first curly bracket int before = i; bool doContinue = false; if (!isFirstBracketFound) { @@ -238,6 +272,12 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string if (doContinue) // Happens for before mentioned case and if no curly bracket is found at all continue; + + if (tokenizedLine[0] is not MultilineStatementOperator && (tokenizedLine[0] is not StringToken || tokenizedLine[1] is not ConcatenationOperator)) + throw new FormatException("Line " + (i+1)); + + if (tokenizedLine[0] is not MultilineStatementOperator) + tokenizedLine = new ArraySegment(tokenizedLine, 2, tokenizedLine.Length - 2).ToArray(); tokens.Add(Parse(tokenizedLine, GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, depth + 1)); @@ -255,7 +295,7 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string } } FullBreak: - + if (i >= lines.Length) throw new FormatException("no matched bracket for bracket on line " + (initialIndex + 1)); From 9f9f7e45a803fdb10a8c7498ab13a65ca66a8d06 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Fri, 12 Aug 2022 23:08:37 +0200 Subject: [PATCH 07/13] Started on actual parsing of members of a simple object --- Parser.cs | 266 ++++++++++++++++++++++++------------------------------ 1 file changed, 118 insertions(+), 148 deletions(-) diff --git a/Parser.cs b/Parser.cs index ce475e6..c7cae28 100644 --- a/Parser.cs +++ b/Parser.cs @@ -8,13 +8,13 @@ using Interpreter.Tokens.Statements.Binary; using Interpreter.Tokens.Statements.Unary; -namespace Interpreter; +namespace Interpreter; public class Parser { public static int GetTopElementIndex(Token[] line, int startIndex, bool isRightBound) { if (line[startIndex] is BinaryStatement or MultilineStatementOperator) return startIndex; - + int highestPriorityNum = -1; int index = -1; for (int i = startIndex; i < line.Length && i >= 0; i += isRightBound ? 1 : -1) { @@ -23,7 +23,7 @@ public static int GetTopElementIndex(Token[] line, int startIndex, bool isRightB numBrackets++; else if (Program.ClosingBrackets.Contains(line[i].Str)) numBrackets--; - + while (numBrackets != 0) { i += isRightBound ? 1 : -1; if (Program.OpeningBrackets.Contains(line[i].Str)) @@ -46,7 +46,7 @@ public static int GetTopElementIndex(Token[] line, int startIndex, bool isRightB return index; } - + public static CheckedString[] CheckComment(CheckedString[] line) { for (int i = 0; i < line.Length; i++) if (line[i].Str == "#") @@ -54,7 +54,7 @@ public static CheckedString[] CheckComment(CheckedString[] line) { return line; } - + /** * This now practically just parses everything, so maybe some refactoring is needed */ @@ -96,15 +96,15 @@ private static Token[] BracketsParse(Token[] line, int i, string[] lines, ref in numBrackets++; else if (Program.ClosingBrackets.Contains(line[j].Str)) numBrackets--; - + while (numBrackets != 0) { if (isRightBound) subLine.Add(line[j]); else subLine = subLine.Prepend(line[j]).ToList(); - + j += isRightBound ? 1 : -1; - + if (Program.OpeningBrackets.Contains(line[j].Str)) numBrackets++; else if (Program.ClosingBrackets.Contains(line[j].Str)) @@ -132,15 +132,15 @@ private static Token[] BracketsParse(Token[] line, int i, string[] lines, ref in arguments.Add(subLine.ToArray()); else arguments = arguments.Prepend(subLine.ToArray()).ToList(); - + // Parse each element in the brackets and put it in a new list List properArguments = new List(); for (int j = 0; j < arguments.Count; j++) properArguments.Add(Parse(arguments[j], GetTopElementIndex(arguments[j].ToArray(), 0, isRightBound), lines, ref lineNo, depth + 1)); - + return properArguments.ToArray(); } - + private static MultilineStatementOperator CurlyBracketsParse(Token[] line, string[] lines, ref int i, Token parent, int depth) { // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree List tokens = new List(); @@ -177,7 +177,7 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin continue; tokens.Add(Parse(tokenizedLine, GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, depth + 1)); - + if (i != before) continue; @@ -190,13 +190,13 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin if (numBrackets == 0) { if (parent is OnStatement onStat && tokenizedLine.Length > 1 && tokenizedLine[1] is ElseStatement) onStat.ElseChild = (ElseStatement) Parse(tokenizedLine, 1, lines, ref i, depth + 1); - + goto FullBreak; } } } FullBreak: - + if (i >= lines.Length) throw new FormatException("no matched bracket for bracket on line " + (initialIndex + 1)); @@ -223,7 +223,7 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string continue; Token[] tokenizedLine = Tokenizer.Tokenize(lexedLine); - + foreach (Token t in tokenizedLine) { if (t.Str == "}") numBrackets--; @@ -238,7 +238,7 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string if (!isFirstBracketFound) continue; - + if (t is CommaSeparator && numBrackets == 1) { properLines.Add(subLine.ToArray()); subLine = new List(); @@ -249,52 +249,22 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string properLines.Add(subLine.ToArray()); goto FullBreak; } - - subLine.Add(t); - } - continue; - // Find first curly bracket - int before = i; - bool doContinue = false; - if (!isFirstBracketFound) { - doContinue = true; - for (int j = 0; j < tokenizedLine.Length; j++) { - if (tokenizedLine[j] is MultilineStatementOperator mso) { - isFirstBracketFound = true; - firstFoundBracket = mso; - tokenizedLine = new ArraySegment(tokenizedLine, j + 1, tokenizedLine.Length - (j + 1)).ToArray(); - doContinue = tokenizedLine.Length == 0; // Happens if first line of declaration ends with an opening curly bracket - break; - } - } + subLine.Add(t); } - if (doContinue) // Happens for before mentioned case and if no curly bracket is found at all - continue; - - if (tokenizedLine[0] is not MultilineStatementOperator && (tokenizedLine[0] is not StringToken || tokenizedLine[1] is not ConcatenationOperator)) - throw new FormatException("Line " + (i+1)); - - if (tokenizedLine[0] is not MultilineStatementOperator) - tokenizedLine = new ArraySegment(tokenizedLine, 2, tokenizedLine.Length - 2).ToArray(); - - tokens.Add(Parse(tokenizedLine, GetTopElementIndex(tokenizedLine, 0, true), lines, ref i, depth + 1)); - - if (i != before) - continue; + } + FullBreak: - foreach (Token t in tokenizedLine) { - if (t.Str == "}") - numBrackets--; - else if (t.Str == "{") - numBrackets++; + foreach (Token[] properLine in properLines) { + // TODO: fix the ConcatenationOperator thing, because right here it's not performing concatenation + if (properLine[0] is not StringToken || properLine[1] is not ConcatenationOperator) + throw new FormatException("simple objects should only consist of declarations"); - if (numBrackets == 0) - goto FullBreak; - } + Token[] parseLine = new ArraySegment(properLine, 2, properLine.Length - 2).ToArray(); + // TODO: add this as value and the key as key to the properties of the object, also, create an object + Parse(parseLine, GetTopElementIndex(parseLine, 0, true), lines, ref i, depth + 1); } - FullBreak: if (i >= lines.Length) throw new FormatException("no matched bracket for bracket on line " + (initialIndex + 1)); @@ -303,7 +273,7 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string return firstFoundBracket; } - + public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, int depth) { Token t = line[i]; @@ -313,46 +283,46 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i line[i].IsDone = true; // Parse only the appropriate section (i.e. Left should only parse to the left and Right only to the right, that's what the array slicing does) - ((BinaryOperator) t).Left = SymmetricBinaryOperatorParse(line.Take(i+1).ToArray(), i, lines, ref lineNo, depth + 1, false); + ((BinaryOperator) t).Left = SymmetricBinaryOperatorParse(line.Take(i + 1).ToArray(), i, lines, ref lineNo, depth + 1, false); ((BinaryOperator) t).Right = SymmetricBinaryOperatorParse(new ArraySegment(line, i, line.Length - i).ToArray(), 0, lines, ref lineNo, depth + 1, true); break; case DeclarationOperator decOp: { - decOp.Left = Parse(line, i + 1, lines, ref lineNo, depth+1); - - if (i + 2 < line.Length) // Only Parse right hand side if it exists - decOp.Right = Parse(line, i + 2, lines, ref lineNo, depth + 1); - break; - } + decOp.Left = Parse(line, i + 1, lines, ref lineNo, depth + 1); + + if (i + 2 < line.Length) // Only Parse right hand side if it exists + decOp.Right = Parse(line, i + 2, lines, ref lineNo, depth + 1); + break; + } case AssignmentOperator assOp: { - assOp.IsDone = true; + assOp.IsDone = true; - int numBrackets = 0; - int j; - // Gets the first variable token to the right of the nearest operator - for (j = i; j >= 0 && line[j + 1] is not VariableToken || j == i; j--) { - if (Program.OpeningBrackets.Contains(line[j].Str)) - numBrackets++; - else if (Program.ClosingBrackets.Contains(line[j].Str)) - numBrackets--; - - while (numBrackets != 0) { - j--; - + int numBrackets = 0; + int j; + // Gets the first variable token to the right of the nearest operator + for (j = i; j >= 0 && line[j + 1] is not VariableToken || j == i; j--) { if (Program.OpeningBrackets.Contains(line[j].Str)) numBrackets++; else if (Program.ClosingBrackets.Contains(line[j].Str)) numBrackets--; + + while (numBrackets != 0) { + j--; + + if (Program.OpeningBrackets.Contains(line[j].Str)) + numBrackets++; + else if (Program.ClosingBrackets.Contains(line[j].Str)) + numBrackets--; + } } - } - if (j >= 0 && line[j] is DotOperator) - j--; - - assOp.Left = Parse(line, j + 1, lines, ref lineNo, depth+1); - Token[] subLine = new ArraySegment(line, i, line.Length - i).ToArray(); - assOp.Right = Parse(subLine, GetTopElementIndex(subLine, 1, true), lines, ref lineNo, depth+1); - break; - } + if (j >= 0 && line[j] is DotOperator) + j--; + + assOp.Left = Parse(line, j + 1, lines, ref lineNo, depth + 1); + Token[] subLine = new ArraySegment(line, i, line.Length - i).ToArray(); + assOp.Right = Parse(subLine, GetTopElementIndex(subLine, 1, true), lines, ref lineNo, depth + 1); + break; + } case ParenthesesOperator parOp: parOp.Children = BracketsParse(line, i, lines, ref lineNo, depth + 1, Program.OpeningBrackets.Contains(line[i].Str)); break; @@ -363,80 +333,80 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i unOp.Child = Parse(line, i + 1, lines, ref lineNo, depth + 1); break; case VariableToken vt: { - if (i + 1 < line.Length) - switch (line[i+1]) { - case ParenthesesOperator: - vt.Args = Parse(line, i + 1, lines, ref lineNo, depth + 1); - break; - case SquareBracketOperator: - vt.Index = Parse(line, i + 1, lines, ref lineNo, depth + 1); - break; - case UnlimitedArgumentOperator: - vt.IsUnlimited = true; - break; - } - break; - } + if (i + 1 < line.Length) + switch (line[i + 1]) { + case ParenthesesOperator: + vt.Args = Parse(line, i + 1, lines, ref lineNo, depth + 1); + break; + case SquareBracketOperator: + vt.Index = Parse(line, i + 1, lines, ref lineNo, depth + 1); + break; + case UnlimitedArgumentOperator: + vt.IsUnlimited = true; + break; + } + break; + } case BinaryStatement statement: { - int addition = 1; - if (t is FunctionStatement fs) { - addition = 2; - fs.Name = line[i + 1].Str; + int addition = 1; + if (t is FunctionStatement fs) { + addition = 2; + fs.Name = line[i + 1].Str; + } + + Token left = Parse(line, i + addition, lines, ref lineNo, depth + 1); + if (left is not ParenthesesOperator po) + throw new FormatException("statement condition/parameter declaration on line " + left.Line + " is missing parentheses"); + + statement.Left = po; + + int numBrackets = 0; + int j = i + 1; + do { + if (Program.ClosingBrackets.Contains(line[j].Str)) + numBrackets--; + else if (Program.OpeningBrackets.Contains(line[j].Str)) + numBrackets++; + + j++; + } while (numBrackets != 0); + + statement.Right = CurlyBracketsParse(line, lines, ref lineNo, statement, depth + 1); + break; } - - Token left = Parse(line, i + addition, lines, ref lineNo, depth + 1); - if (left is not ParenthesesOperator po) - throw new FormatException("statement condition/parameter declaration on line " + left.Line + " is missing parentheses"); - - statement.Left = po; - - int numBrackets = 0; - int j = i+1; - do { - if (Program.ClosingBrackets.Contains(line[j].Str)) - numBrackets--; - else if (Program.OpeningBrackets.Contains(line[j].Str)) - numBrackets++; - - j++; - } while (numBrackets != 0); - - statement.Right = CurlyBracketsParse(line, lines, ref lineNo, statement, depth + 1); - break; - } case ElseStatement or ClassStatement: { - if (t is ClassStatement classStat) - classStat.Name = line[i + 1].Str; - - Token child = CurlyBracketsParse(line, lines, ref lineNo, t, depth + 1); - if (child is not MultilineStatementOperator mso) - throw new FormatException("statement argument on line " + child.Line + " needs curly brackets"); - - ((UnaryStatement) t).Child = mso; - break; - } + if (t is ClassStatement classStat) + classStat.Name = line[i + 1].Str; + + Token child = CurlyBracketsParse(line, lines, ref lineNo, t, depth + 1); + if (child is not MultilineStatementOperator mso) + throw new FormatException("statement argument on line " + child.Line + " needs curly brackets"); + + ((UnaryStatement) t).Child = mso; + break; + } case UnaryStatement unStat: { - Token child = Parse(line, i + 1, lines, ref lineNo, depth + 1); - if (child is not ParenthesesOperator po) - throw new FormatException("statement argument on line " + child.Line + " is missing parentheses"); + Token child = Parse(line, i + 1, lines, ref lineNo, depth + 1); + if (child is not ParenthesesOperator po) + throw new FormatException("statement argument on line " + child.Line + " is missing parentheses"); - unStat.Child = po; - break; - } - case MultilineStatementOperator mso: { - if (mso.Str == "}") + unStat.Child = po; break; + } + case MultilineStatementOperator mso: { + if (mso.Str == "}") + break; - // TODO: fix this weird property copying and add this to statement parsing and also fix parsing for simple objects - mso.Children = SimpleObjectParse(line, lines, ref lineNo, depth + 1).Children; - break; - } + // TODO: fix this weird property copying and add this to statement parsing and also fix parsing for simple objects + mso.Children = SimpleObjectParse(line, lines, ref lineNo, depth + 1).Children; + break; + } } t.Line = line[i].Line; line[i].IsDone = true; - + return t; } } \ No newline at end of file From 022693e7586f88c1678b94d792005019f8856d52 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Sat, 13 Aug 2022 14:09:13 +0200 Subject: [PATCH 08/13] Completed parsing of simple objects without support for evaluation yet --- Parser.cs | 205 +++++++++--------- .../Binary/ObjectAssignmentOperator.cs | 15 ++ 2 files changed, 118 insertions(+), 102 deletions(-) create mode 100644 Tokens/Operators/Binary/ObjectAssignmentOperator.cs diff --git a/Parser.cs b/Parser.cs index c7cae28..fa51e5a 100644 --- a/Parser.cs +++ b/Parser.cs @@ -142,7 +142,6 @@ private static Token[] BracketsParse(Token[] line, int i, string[] lines, ref in } private static MultilineStatementOperator CurlyBracketsParse(Token[] line, string[] lines, ref int i, Token parent, int depth) { - // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree List tokens = new List(); int initialIndex = i; int numBrackets = 1; @@ -205,40 +204,41 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin return firstFoundBracket; } - private static MultilineStatementOperator SimpleObjectParse(Token[] line, string[] lines, ref int i, int depth) { - // Get copy of vars so that it doesn't get affected by method calls lower in the recursion tree + private static ObjectAssignmentOperator[] SimpleObjectParse(Token[] line, string[] lines, ref int i, int startIndex, int depth) { List tokens = new List(); int initialIndex = i; int numBrackets = 0; - bool isFirstBracketFound = false; - MultilineStatementOperator firstFoundBracket = null!; List properLines = new List(); List subLine = new List(); for (; i < lines.Length; i++) { - // TODO: Match : - CheckedString[] lexedLine = Lexer.Lex(lines[i], i + 1); + Token[] tokenizedLine; + if (i == initialIndex) { + tokenizedLine = line; + } else { + CheckedString[] lexedLine = Lexer.Lex(lines[i], i + 1); + + lexedLine = CheckComment(lexedLine); + if (lexedLine.Length == 0) + continue; - lexedLine = CheckComment(lexedLine); - if (lexedLine.Length == 0) - continue; + tokenizedLine = Tokenizer.Tokenize(lexedLine); + } - Token[] tokenizedLine = Tokenizer.Tokenize(lexedLine); + for (int j = 0; j < tokenizedLine.Length; j++) { + if (i == initialIndex) + j = startIndex; - foreach (Token t in tokenizedLine) { + Token t = tokenizedLine[j]; if (t.Str == "}") numBrackets--; else if (t.Str == "{") { - if (!isFirstBracketFound) { - isFirstBracketFound = true; + if (numBrackets == 0) { // Exclude opening bracket from line numBrackets++; continue; } numBrackets++; } - if (!isFirstBracketFound) - continue; - if (t is CommaSeparator && numBrackets == 1) { properLines.Add(subLine.ToArray()); subLine = new List(); @@ -256,6 +256,7 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string } FullBreak: + List objectBody = new List(); foreach (Token[] properLine in properLines) { // TODO: fix the ConcatenationOperator thing, because right here it's not performing concatenation if (properLine[0] is not StringToken || properLine[1] is not ConcatenationOperator) @@ -263,15 +264,16 @@ private static MultilineStatementOperator SimpleObjectParse(Token[] line, string Token[] parseLine = new ArraySegment(properLine, 2, properLine.Length - 2).ToArray(); // TODO: add this as value and the key as key to the properties of the object, also, create an object - Parse(parseLine, GetTopElementIndex(parseLine, 0, true), lines, ref i, depth + 1); + ObjectAssignmentOperator objAssOp = new ObjectAssignmentOperator(); + objAssOp.Left = properLine[0]; + objAssOp.Right = Parse(parseLine, GetTopElementIndex(parseLine, 0, true), lines, ref i, depth + 1); + objectBody.Add(objAssOp); } if (i >= lines.Length) throw new FormatException("no matched bracket for bracket on line " + (initialIndex + 1)); - firstFoundBracket.Children = tokens.ToArray(); - - return firstFoundBracket; + return objectBody.ToArray(); } public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, int depth) { @@ -287,42 +289,42 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i ((BinaryOperator) t).Right = SymmetricBinaryOperatorParse(new ArraySegment(line, i, line.Length - i).ToArray(), 0, lines, ref lineNo, depth + 1, true); break; case DeclarationOperator decOp: { - decOp.Left = Parse(line, i + 1, lines, ref lineNo, depth + 1); + decOp.Left = Parse(line, i + 1, lines, ref lineNo, depth + 1); - if (i + 2 < line.Length) // Only Parse right hand side if it exists - decOp.Right = Parse(line, i + 2, lines, ref lineNo, depth + 1); - break; - } + if (i + 2 < line.Length) // Only Parse right hand side if it exists + decOp.Right = Parse(line, i + 2, lines, ref lineNo, depth + 1); + break; + } case AssignmentOperator assOp: { - assOp.IsDone = true; + assOp.IsDone = true; + + int numBrackets = 0; + int j; + // Gets the first variable token to the right of the nearest operator + for (j = i; j >= 0 && line[j + 1] is not VariableToken || j == i; j--) { + if (Program.OpeningBrackets.Contains(line[j].Str)) + numBrackets++; + else if (Program.ClosingBrackets.Contains(line[j].Str)) + numBrackets--; + + while (numBrackets != 0) { + j--; - int numBrackets = 0; - int j; - // Gets the first variable token to the right of the nearest operator - for (j = i; j >= 0 && line[j + 1] is not VariableToken || j == i; j--) { if (Program.OpeningBrackets.Contains(line[j].Str)) numBrackets++; else if (Program.ClosingBrackets.Contains(line[j].Str)) numBrackets--; - - while (numBrackets != 0) { - j--; - - if (Program.OpeningBrackets.Contains(line[j].Str)) - numBrackets++; - else if (Program.ClosingBrackets.Contains(line[j].Str)) - numBrackets--; - } } + } - if (j >= 0 && line[j] is DotOperator) - j--; + if (j >= 0 && line[j] is DotOperator) + j--; - assOp.Left = Parse(line, j + 1, lines, ref lineNo, depth + 1); - Token[] subLine = new ArraySegment(line, i, line.Length - i).ToArray(); - assOp.Right = Parse(subLine, GetTopElementIndex(subLine, 1, true), lines, ref lineNo, depth + 1); - break; - } + assOp.Left = Parse(line, j + 1, lines, ref lineNo, depth + 1); + Token[] subLine = new ArraySegment(line, i, line.Length - i).ToArray(); + assOp.Right = Parse(subLine, GetTopElementIndex(subLine, 1, true), lines, ref lineNo, depth + 1); + break; + } case ParenthesesOperator parOp: parOp.Children = BracketsParse(line, i, lines, ref lineNo, depth + 1, Program.OpeningBrackets.Contains(line[i].Str)); break; @@ -333,74 +335,73 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i unOp.Child = Parse(line, i + 1, lines, ref lineNo, depth + 1); break; case VariableToken vt: { - if (i + 1 < line.Length) - switch (line[i + 1]) { - case ParenthesesOperator: - vt.Args = Parse(line, i + 1, lines, ref lineNo, depth + 1); - break; - case SquareBracketOperator: - vt.Index = Parse(line, i + 1, lines, ref lineNo, depth + 1); - break; - case UnlimitedArgumentOperator: - vt.IsUnlimited = true; - break; - } - break; - } - case BinaryStatement statement: { - int addition = 1; - if (t is FunctionStatement fs) { - addition = 2; - fs.Name = line[i + 1].Str; + if (i + 1 < line.Length) + switch (line[i + 1]) { + case ParenthesesOperator: + vt.Args = Parse(line, i + 1, lines, ref lineNo, depth + 1); + break; + case SquareBracketOperator: + vt.Index = Parse(line, i + 1, lines, ref lineNo, depth + 1); + break; + case UnlimitedArgumentOperator: + vt.IsUnlimited = true; + break; } + break; + } + case BinaryStatement statement: { + int addition = 1; + if (t is FunctionStatement fs) { + addition = 2; + fs.Name = line[i + 1].Str; + } - Token left = Parse(line, i + addition, lines, ref lineNo, depth + 1); - if (left is not ParenthesesOperator po) - throw new FormatException("statement condition/parameter declaration on line " + left.Line + " is missing parentheses"); + Token left = Parse(line, i + addition, lines, ref lineNo, depth + 1); + if (left is not ParenthesesOperator po) + throw new FormatException("statement condition/parameter declaration on line " + left.Line + " is missing parentheses"); - statement.Left = po; + statement.Left = po; - int numBrackets = 0; - int j = i + 1; - do { - if (Program.ClosingBrackets.Contains(line[j].Str)) - numBrackets--; - else if (Program.OpeningBrackets.Contains(line[j].Str)) - numBrackets++; + int numBrackets = 0; + int j = i + 1; + do { + if (Program.ClosingBrackets.Contains(line[j].Str)) + numBrackets--; + else if (Program.OpeningBrackets.Contains(line[j].Str)) + numBrackets++; - j++; - } while (numBrackets != 0); + j++; + } while (numBrackets != 0); - statement.Right = CurlyBracketsParse(line, lines, ref lineNo, statement, depth + 1); - break; - } + statement.Right = CurlyBracketsParse(line, lines, ref lineNo, statement, depth + 1); + break; + } case ElseStatement or ClassStatement: { - if (t is ClassStatement classStat) - classStat.Name = line[i + 1].Str; + if (t is ClassStatement classStat) + classStat.Name = line[i + 1].Str; - Token child = CurlyBracketsParse(line, lines, ref lineNo, t, depth + 1); - if (child is not MultilineStatementOperator mso) - throw new FormatException("statement argument on line " + child.Line + " needs curly brackets"); + Token child = CurlyBracketsParse(line, lines, ref lineNo, t, depth + 1); + if (child is not MultilineStatementOperator mso) + throw new FormatException("statement argument on line " + child.Line + " needs curly brackets"); - ((UnaryStatement) t).Child = mso; - break; - } + ((UnaryStatement) t).Child = mso; + break; + } case UnaryStatement unStat: { - Token child = Parse(line, i + 1, lines, ref lineNo, depth + 1); - if (child is not ParenthesesOperator po) - throw new FormatException("statement argument on line " + child.Line + " is missing parentheses"); + Token child = Parse(line, i + 1, lines, ref lineNo, depth + 1); + if (child is not ParenthesesOperator po) + throw new FormatException("statement argument on line " + child.Line + " is missing parentheses"); - unStat.Child = po; - break; - } + unStat.Child = po; + break; + } case MultilineStatementOperator mso: { - if (mso.Str == "}") - break; - - // TODO: fix this weird property copying and add this to statement parsing and also fix parsing for simple objects - mso.Children = SimpleObjectParse(line, lines, ref lineNo, depth + 1).Children; + if (mso.Str == "}") break; - } + + mso.Children = SimpleObjectParse(line, lines, ref lineNo, i, depth + 1); + break; + } } t.Line = line[i].Line; diff --git a/Tokens/Operators/Binary/ObjectAssignmentOperator.cs b/Tokens/Operators/Binary/ObjectAssignmentOperator.cs new file mode 100644 index 0000000..ac10efe --- /dev/null +++ b/Tokens/Operators/Binary/ObjectAssignmentOperator.cs @@ -0,0 +1,15 @@ +using System; +using TrieDictionary; +using Object = Interpreter.Types.Object; + +namespace Interpreter.Tokens.Operators.Binary; +public class ObjectAssignmentOperator : BinaryOperator { + public ObjectAssignmentOperator() { + Symbol = ":"; + } + + public override Object Evaluate(List> vars) { + throw new NotImplementedException(); + } +} + From 4be024a0a5b690748b2fae6f83eee5c2e1964586 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Sat, 13 Aug 2022 14:14:34 +0200 Subject: [PATCH 09/13] Removed todo --- Parser.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Parser.cs b/Parser.cs index fa51e5a..05f79b8 100644 --- a/Parser.cs +++ b/Parser.cs @@ -263,7 +263,6 @@ private static ObjectAssignmentOperator[] SimpleObjectParse(Token[] line, string throw new FormatException("simple objects should only consist of declarations"); Token[] parseLine = new ArraySegment(properLine, 2, properLine.Length - 2).ToArray(); - // TODO: add this as value and the key as key to the properties of the object, also, create an object ObjectAssignmentOperator objAssOp = new ObjectAssignmentOperator(); objAssOp.Left = properLine[0]; objAssOp.Right = Parse(parseLine, GetTopElementIndex(parseLine, 0, true), lines, ref i, depth + 1); From 81dfa306e427f2496b5f2b1f696ecb2e950431c5 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Tue, 16 Aug 2022 23:44:08 +0200 Subject: [PATCH 10/13] Implemented evaluation of simple objects (Dictionary) --- Parser.cs | 9 +++++---- .../Binary/DictionaryAssignmentOperator.cs | 15 +++++++++++++++ Tokens/Operators/Binary/DotOperator.cs | 3 ++- .../Binary/ObjectAssignmentOperator.cs | 15 --------------- .../N-Ary/MultilineStatementOperator.cs | 13 +++++++++++++ Types/Dictionary.cs | 16 ++++++++++++++++ Types/Util/DictionaryEntry.cs | 17 +++++++++++++++++ 7 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 Tokens/Operators/Binary/DictionaryAssignmentOperator.cs delete mode 100644 Tokens/Operators/Binary/ObjectAssignmentOperator.cs create mode 100644 Types/Dictionary.cs create mode 100644 Types/Util/DictionaryEntry.cs diff --git a/Parser.cs b/Parser.cs index 05f79b8..4e5a353 100644 --- a/Parser.cs +++ b/Parser.cs @@ -204,7 +204,7 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin return firstFoundBracket; } - private static ObjectAssignmentOperator[] SimpleObjectParse(Token[] line, string[] lines, ref int i, int startIndex, int depth) { + private static DictionaryAssignmentOperator[] SimpleObjectParse(Token[] line, string[] lines, ref int i, int startIndex, int depth) { List tokens = new List(); int initialIndex = i; int numBrackets = 0; @@ -256,14 +256,14 @@ private static ObjectAssignmentOperator[] SimpleObjectParse(Token[] line, string } FullBreak: - List objectBody = new List(); + List objectBody = new List(); foreach (Token[] properLine in properLines) { // TODO: fix the ConcatenationOperator thing, because right here it's not performing concatenation if (properLine[0] is not StringToken || properLine[1] is not ConcatenationOperator) throw new FormatException("simple objects should only consist of declarations"); Token[] parseLine = new ArraySegment(properLine, 2, properLine.Length - 2).ToArray(); - ObjectAssignmentOperator objAssOp = new ObjectAssignmentOperator(); + DictionaryAssignmentOperator objAssOp = new DictionaryAssignmentOperator(); objAssOp.Left = properLine[0]; objAssOp.Right = Parse(parseLine, GetTopElementIndex(parseLine, 0, true), lines, ref i, depth + 1); objectBody.Add(objAssOp); @@ -394,11 +394,12 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i unStat.Child = po; break; } - case MultilineStatementOperator mso: { + case MultilineStatementOperator mso: { // TODO: fix parsing of nested dictionaries if (mso.Str == "}") break; mso.Children = SimpleObjectParse(line, lines, ref lineNo, i, depth + 1); + mso.IsDictionary = true; break; } } diff --git a/Tokens/Operators/Binary/DictionaryAssignmentOperator.cs b/Tokens/Operators/Binary/DictionaryAssignmentOperator.cs new file mode 100644 index 0000000..d8cbed1 --- /dev/null +++ b/Tokens/Operators/Binary/DictionaryAssignmentOperator.cs @@ -0,0 +1,15 @@ +using TrieDictionary; +using Interpreter.Types.Util; +using String = Interpreter.Types.Comparable.String; +using Object = Interpreter.Types.Object; + +namespace Interpreter.Tokens.Operators.Binary; + +public class DictionaryAssignmentOperator : BinaryOperator { + public DictionaryAssignmentOperator() { + Symbol = ":"; + } + + public override Object Evaluate(List> vars) => new DictionaryEntry((String) Left.Evaluate(vars), Right.Evaluate(vars)); +} + diff --git a/Tokens/Operators/Binary/DotOperator.cs b/Tokens/Operators/Binary/DotOperator.cs index fac8064..b1b1d4d 100644 --- a/Tokens/Operators/Binary/DotOperator.cs +++ b/Tokens/Operators/Binary/DotOperator.cs @@ -1,6 +1,7 @@ using Interpreter.Types.Comparable; using Interpreter.Types.Function; using Interpreter.Types.Util; +using Interpreter.Types; using TrieDictionary; using Array = Interpreter.Types.Array; using Object = Interpreter.Types.Object; @@ -14,7 +15,7 @@ public DotOperator() { public override Object Evaluate(List> vars) { Object leftObj = Left.Evaluate(vars); - Object res = leftObj.Properties[Right.Str]; + Object res = leftObj.Properties.Contains(Right.Str) ? leftObj.Properties[Right.Str] : new Null(); VariableToken properRight = (VariableToken) Right; if (res is Function f) { diff --git a/Tokens/Operators/Binary/ObjectAssignmentOperator.cs b/Tokens/Operators/Binary/ObjectAssignmentOperator.cs deleted file mode 100644 index ac10efe..0000000 --- a/Tokens/Operators/Binary/ObjectAssignmentOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using TrieDictionary; -using Object = Interpreter.Types.Object; - -namespace Interpreter.Tokens.Operators.Binary; -public class ObjectAssignmentOperator : BinaryOperator { - public ObjectAssignmentOperator() { - Symbol = ":"; - } - - public override Object Evaluate(List> vars) { - throw new NotImplementedException(); - } -} - diff --git a/Tokens/Operators/N-Ary/MultilineStatementOperator.cs b/Tokens/Operators/N-Ary/MultilineStatementOperator.cs index e9a37e3..126e144 100644 --- a/Tokens/Operators/N-Ary/MultilineStatementOperator.cs +++ b/Tokens/Operators/N-Ary/MultilineStatementOperator.cs @@ -1,11 +1,14 @@ using Interpreter.Tokens.Statements.Binary; using Interpreter.Tokens.Statements.Unary; +using Interpreter.Types.Util; using TrieDictionary; using Object = Interpreter.Types.Object; +using Dictionary = Interpreter.Types.Dictionary; namespace Interpreter.Tokens.Operators.N_Ary; public class MultilineStatementOperator : NAryOperator { + public bool IsDictionary = false; public bool IsPartOfFunction = false; public MultilineStatementOperator() { @@ -13,6 +16,16 @@ public MultilineStatementOperator() { } public override Object Evaluate(List> vars) { + if (IsDictionary) { + Dictionary dictionary = new Dictionary(); + foreach (Token t in Children) { + DictionaryEntry entry = (DictionaryEntry) t.Evaluate(vars); + dictionary.Properties[entry.Key.Str] = entry.Value; + } + + return dictionary; + } + foreach (Token t in Children) { if (t is ReturnStatement) { if (!IsPartOfFunction) diff --git a/Types/Dictionary.cs b/Types/Dictionary.cs new file mode 100644 index 0000000..aa46b71 --- /dev/null +++ b/Types/Dictionary.cs @@ -0,0 +1,16 @@ +using System.Text; + +namespace Interpreter.Types; + +public class Dictionary : Object { + public override string GetType() => "Dictionary"; + + public override string ToString() { // TODO: Make this indent nested dictionaries correctly + StringBuilder sb = new StringBuilder("{\n"); + foreach (string s in Properties.GetKeySet()) + sb.Append($"\t{s}: {Properties[s].ToString()}\n"); + sb.Append('}'); + + return sb.ToString(); + } +} diff --git a/Types/Util/DictionaryEntry.cs b/Types/Util/DictionaryEntry.cs new file mode 100644 index 0000000..2af19eb --- /dev/null +++ b/Types/Util/DictionaryEntry.cs @@ -0,0 +1,17 @@ +namespace Interpreter.Types.Util; +using String = Comparable.String; + +public class DictionaryEntry : Object { + public String Key; + public Object Value; + + public DictionaryEntry(String key, Object value) { + Key = key; + Value = value; + } + + public override string GetType() => "DictionaryEntry"; + + public override string ToString() => $"\"{Key}\": {Value.ToString()}"; +} + From 55f2097ad1ea40588c65eb77b4f38988c2556699 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Tue, 16 Aug 2022 23:51:21 +0200 Subject: [PATCH 11/13] Fixed DictionaryEntry import --- Types/Util/DictionaryEntry.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Types/Util/DictionaryEntry.cs b/Types/Util/DictionaryEntry.cs index 2af19eb..423a46e 100644 --- a/Types/Util/DictionaryEntry.cs +++ b/Types/Util/DictionaryEntry.cs @@ -1,5 +1,6 @@ -namespace Interpreter.Types.Util; -using String = Comparable.String; +using String = Interpreter.Types.Comparable.String; + +namespace Interpreter.Types.Util; public class DictionaryEntry : Object { public String Key; From dc32f322ea962f7fab2b936194211b5ad74a2084 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Wed, 17 Aug 2022 23:11:32 +0200 Subject: [PATCH 12/13] Fixed one-line dictionary declaration parsing and nested dictionary parsing --- Parser.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Parser.cs b/Parser.cs index 4e5a353..3c5698d 100644 --- a/Parser.cs +++ b/Parser.cs @@ -205,15 +205,16 @@ private static MultilineStatementOperator CurlyBracketsParse(Token[] line, strin } private static DictionaryAssignmentOperator[] SimpleObjectParse(Token[] line, string[] lines, ref int i, int startIndex, int depth) { - List tokens = new List(); int initialIndex = i; int numBrackets = 0; List properLines = new List(); List subLine = new List(); for (; i < lines.Length; i++) { Token[] tokenizedLine; + int j = 0; if (i == initialIndex) { tokenizedLine = line; + j = startIndex; } else { CheckedString[] lexedLine = Lexer.Lex(lines[i], i + 1); @@ -224,10 +225,7 @@ private static DictionaryAssignmentOperator[] SimpleObjectParse(Token[] line, st tokenizedLine = Tokenizer.Tokenize(lexedLine); } - for (int j = 0; j < tokenizedLine.Length; j++) { - if (i == initialIndex) - j = startIndex; - + for (; j < tokenizedLine.Length; j++) { Token t = tokenizedLine[j]; if (t.Str == "}") numBrackets--; @@ -252,7 +250,6 @@ private static DictionaryAssignmentOperator[] SimpleObjectParse(Token[] line, st subLine.Add(t); } - } FullBreak: @@ -398,6 +395,8 @@ public static Token Parse(Token[] line, int i, string[] lines, ref int lineNo, i if (mso.Str == "}") break; + // If for some reason the Token[] is changed within mso and an element is replaced by a type + // which is not a subclass or superclass of DictionaryAssignmentOperator, the program will error, but that should never happen mso.Children = SimpleObjectParse(line, lines, ref lineNo, i, depth + 1); mso.IsDictionary = true; break; From c0eaffc02dd66e03134c3b22b2bc67c51cc195f3 Mon Sep 17 00:00:00 2001 From: DemonExposer Date: Thu, 18 Aug 2022 18:56:05 +0200 Subject: [PATCH 13/13] Fixed printing of nested dictionaries --- Types/Dictionary.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Types/Dictionary.cs b/Types/Dictionary.cs index aa46b71..79effe1 100644 --- a/Types/Dictionary.cs +++ b/Types/Dictionary.cs @@ -5,11 +5,18 @@ namespace Interpreter.Types; public class Dictionary : Object { public override string GetType() => "Dictionary"; - public override string ToString() { // TODO: Make this indent nested dictionaries correctly - StringBuilder sb = new StringBuilder("{\n"); + public override string ToString() => ToString(0); + + public string ToString(int indent) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) + sb.Append('\t'); + string indentStr = sb.ToString(); + + sb = new StringBuilder("{\n"); foreach (string s in Properties.GetKeySet()) - sb.Append($"\t{s}: {Properties[s].ToString()}\n"); - sb.Append('}'); + sb.Append(indentStr).Append($"\t{s}: {(Properties[s] is Dictionary dict ? dict.ToString(indent + 1) : Properties[s].ToString())}\n"); + sb.Append(indentStr).Append('}'); return sb.ToString(); }