diff --git a/source/parsing/treegen/astTypes.d b/source/parsing/treegen/astTypes.d index e5a4b5c..015eb41 100644 --- a/source/parsing/treegen/astTypes.d +++ b/source/parsing/treegen/astTypes.d @@ -107,13 +107,13 @@ enum OperationVariety struct SingleArgumentOperationNodeData { - OperationVariety pperationVariety; + OperationVariety operationVariety; AstNode value; } struct DoubleArgumentOperationNodeData { - OperationVariety pperationVariety; + OperationVariety operationVariety; AstNode left; AstNode right; } @@ -180,11 +180,50 @@ class AstNode case AstAction.LiteralUnit: sink(literalUnitCompenents.to!string); break; + case AstAction.DoubleArgumentOperation: + sink(doubleArgumentOperationNodeData.operationVariety.to!string); + sink(", "); + sink(doubleArgumentOperationNodeData.left.to!string); + sink(", "); + sink(doubleArgumentOperationNodeData.right.to!string); + break; default: break; } sink("}"); } + + void tree(size_t tabCount) + { + import std.stdio; + import std.conv; + + foreach (i; 0 .. tabCount) + write("| "); + + switch (action) + { + case AstAction.Call: + writeln(callNodeData.func.to!string ~ ":"); + callNodeData.args.tree(tabCount + 1); + break; + case AstAction.DoubleArgumentOperation: + writeln(doubleArgumentOperationNodeData.operationVariety.to!string ~ ":"); + doubleArgumentOperationNodeData.left.tree(tabCount + 1); + doubleArgumentOperationNodeData.right.tree(tabCount + 1); + break; + case AstAction.Expression: + writeln("Result of expression with " ~ expressionNodeData.components.length.to!string ~ " components:"); + foreach (subnode; expressionNodeData.components) + { + subnode.tree(tabCount + 1); + } + break; + default: + writeln(this.to!string); + break; + } + } } // struct ScopeParsingMode{ @@ -203,6 +242,7 @@ Nullable!AstNode nextNonWhiteNode(Array!AstNode nodes, ref size_t index) while (nodes.length > index) { import parsing.tokenizer.tokens; + AstNode node = nodes[index++]; if (node.action == AstAction.TokenHolder && (node.tokenBeingHeld.tokenVariety == TokenType.WhiteSpace diff --git a/source/parsing/treegen/expressionParser.d b/source/parsing/treegen/expressionParser.d index 3221733..4173059 100644 --- a/source/parsing/treegen/expressionParser.d +++ b/source/parsing/treegen/expressionParser.d @@ -91,7 +91,7 @@ private void phaseTwo(Array!AstNode nodes){ Array!AstNode components; components~=args.expressionNodeData.components; phaseTwo(components); - operatorPairingPhase(components); + scanAndMergeOperators(components); args.expressionNodeData.components.length = components.data.length; args.expressionNodeData.components[0..$] = components.data[0..$]; @@ -108,7 +108,7 @@ private void phaseTwo(Array!AstNode nodes){ Array!AstNode components; components~=node.expressionNodeData.components; phaseTwo(components); - operatorPairingPhase(components); + scanAndMergeOperators(components); node.expressionNodeData.components.length = components.data.length; node.expressionNodeData.components[0..$] = components.data[0..$]; } @@ -122,12 +122,12 @@ unittest { import parsing.tokenizer.make_tokens; - AstNode[] phaseOneNodes = phaseOne("3*5+6*7/2".tokenizeText); + AstNode[] phaseOneNodes = phaseOne("math.sqrt(3*5+6*7/2)*3".tokenizeText); Array!AstNode nodes; nodes~=phaseOneNodes; phaseTwo(nodes); - nodes.scanForOperators; - nodes.writeln; + scanAndMergeOperators(nodes); + nodes[0].tree(0); } \ No newline at end of file diff --git a/source/parsing/treegen/tokenRelationships.d b/source/parsing/treegen/tokenRelationships.d index bb2de8a..499a311 100644 --- a/source/parsing/treegen/tokenRelationships.d +++ b/source/parsing/treegen/tokenRelationships.d @@ -272,8 +272,8 @@ struct OperationPrecedenceEntry } private Token OPR(dchar o) -{ - return Token(o != '=' ?TokenType.Operator : TokenType.Equals, [o]); +{ + return Token(o != '=' ? TokenType.Operator : TokenType.Equals, [o]); } // https://en.cppreference.com/w/c/language/operator_precedence @@ -433,94 +433,106 @@ const OperatorPrecedenceLayer[] operatorPrecedence = [ ]; import std.container.array; -private bool testAstEntry(const(OperationPrecedenceEntry) entry, AstNode[] nodes){ + +private bool testAstEntry(const(OperationPrecedenceEntry) entry, AstNode[] nodes) +{ if (entry.tokens.length > nodes.length) return false; - for(size_t index = 0; index < entry.tokens.length; index++){ - switch (entry.tokens[index].tokenVariety){ - case TokenType.Filler: - AstNode node = nodes[index]; - if (node.action == AstAction.TokenHolder || node.action == AstAction.Keyword || node.action == AstAction.Scope) - return false; - break; - case TokenType.Operator: - AstNode node = nodes[index]; - if (node.action != AstAction.TokenHolder) - return false; - Token token = node.tokenBeingHeld; - if (token.tokenVariety != TokenType.Equals && token.tokenVariety != TokenType.Operator) - return false; - if (token.value != entry.tokens[index].value) - return false; - break; - default: - // entry.tokens[index].writeln; - assert(0); - + for (size_t index = 0; index < entry.tokens.length; index++) + { + switch (entry.tokens[index].tokenVariety) + { + case TokenType.Filler: + AstNode node = nodes[index]; + if (node.action == AstAction.TokenHolder || node.action == AstAction.Keyword || node.action == AstAction + .Scope) + return false; + break; + case TokenType.Operator: + AstNode node = nodes[index]; + if (node.action != AstAction.TokenHolder) + return false; + Token token = node.tokenBeingHeld; + if (token.tokenVariety != TokenType.Equals && token.tokenVariety != TokenType.Operator) + return false; + if (token.value != entry.tokens[index].value) + return false; + break; + default: + // entry.tokens[index].writeln; + assert(0); + } } return true; } -private void merge(const(OperationPrecedenceEntry) entry, Array!AstNode nodes, size_t startIndex){ - AstNode[] nodeData; - for(size_t index = 0; index < entry.tokens.length; index++){ - switch (entry.tokens[index].tokenVariety){ - case TokenType.Filler: - nodeData ~= nodes[startIndex + index]; - break; - case TokenType.Operator: - break; - default: - assert(0); +private void merge(const(OperationPrecedenceEntry) entry, ref Array!AstNode nodes, size_t startIndex) +{ + AstNode[] nodeData; + for (size_t index = 0; index < entry.tokens.length; index++) + { + switch (entry.tokens[index].tokenVariety) + { + case TokenType.Filler: + nodeData ~= nodes[startIndex + index]; + break; + case TokenType.Operator: + break; + default: + assert(0); } } AstNode oprNode = new AstNode(); oprNode.action = AstAction.DoubleArgumentOperation; - oprNode.doubleArgumentOperationNodeData = DoubleArgumentOperationNodeData( - entry.operation, - nodeData[0], - nodeData[1] - ); + if (nodeData.length == 0) + assert(0); + if (nodeData.length == 1) + { + oprNode.action = AstAction.SingleArgumentOperation; + oprNode.singleArgumentOperationNodeData = SingleArgumentOperationNodeData( + entry.operation, + nodeData[0], + ); + } + if (nodeData.length == 2) + oprNode.doubleArgumentOperationNodeData = DoubleArgumentOperationNodeData( + entry.operation, + nodeData[0], + nodeData[1] + ); + nodes[startIndex] = oprNode; - nodes.linearRemove(nodes[startIndex+1..startIndex+entry.tokens.length]); + nodes.linearRemove(nodes[startIndex + 1 .. startIndex + entry.tokens.length]); } -void scanForOperators(Array!AstNode nodes){ +void scanAndMergeOperators(Array!AstNode nodes) +{ // OperatorOrder order; auto data = nodes.data; static foreach (layer; operatorPrecedence) { - static if (layer.order == OperatorOrder.LeftToRight){ - for (size_t index = 0; index < nodes.length; index++){ - // layer.layer.writeln; - // nodes.data.writeln; + static if (layer.order == OperatorOrder.LeftToRight) + { + for (size_t index = 0; index < nodes.length; index++) + { foreach (entry; layer.layer) { - // entry.writeln; - // data[index..$].writeln; - bool isEntry = entry.testAstEntry(data[index..$]); - if (isEntry) entry.merge(nodes, index); + if (entry.testAstEntry(data[index .. $])) + entry.merge(nodes, index); + } + + } + } + static if (layer.order == OperatorOrder.RightToLeft){ + for (size_t index = nodes.length; index != -1; index--){ + foreach (entry; layer.layer) + { + if (entry.testAstEntry(data[index .. $])) + entry.merge(nodes, index); } - } - } - // static if (layer.order == OperatorOrder.RightToLeft){ - // "right".writeln; - // for (size_t index = nodes.length; index != -1; index--){ - // foreach (entry; layer.layer) - // { - // bool isEntry = entry.testAstEntry(nodes.data[index..$]); - // if (isEntry) entry.operation.writeln; - // } - // } - // } - // order = layer.order; - // foreach (entry; layer.layer) - // { - - // } } -} \ No newline at end of file +}