From 3dfb0044b96966a8ed1c5cd9e42078e052350a20 Mon Sep 17 00:00:00 2001 From: Jacob Misirian Date: Mon, 12 Sep 2016 22:08:21 -0500 Subject: [PATCH] Added multi assignment. a, b, c = 2; --- src/Hassium/Compiler/CodeGen/Compiler.cs | 7 +++++ .../Parser/Ast/MultiAssignmentNode.cs | 30 +++++++++++++++++++ src/Hassium/Compiler/Parser/IVisitor.cs | 1 + src/Hassium/Compiler/Parser/Parser.cs | 16 ++++++++++ .../SemanticAnalysis/SemanticAnalyzer.cs | 1 + src/Hassium/Hassium.csproj | 1 + .../Runtime/Objects/HassiumFunction.cs | 9 ++++++ src/Hassium/Runtime/Objects/HassiumMethod.cs | 6 ++++ 8 files changed, 71 insertions(+) create mode 100644 src/Hassium/Compiler/Parser/Ast/MultiAssignmentNode.cs diff --git a/src/Hassium/Compiler/CodeGen/Compiler.cs b/src/Hassium/Compiler/CodeGen/Compiler.cs index d7aa205..99d484c 100755 --- a/src/Hassium/Compiler/CodeGen/Compiler.cs +++ b/src/Hassium/Compiler/CodeGen/Compiler.cs @@ -488,6 +488,11 @@ public void Accept(ListDeclarationNode node) val.Visit(this); method.Emit(node.SourceLocation, InstructionType.BuildList, node.InitialValues.Count); } + public void Accept(MultiAssignmentNode node) + { + foreach (var assign in node.Assignments) + assign.Visit(this); + } public void Accept(PropertyNode node) { module.Attributes.Add(node.Variable, compileProperty(node, method.Parent)); @@ -775,6 +780,8 @@ private string locateFile(string path, string extension) Environment.OSVersion.Platform == PlatformID.MacOSX) ? Environment.GetEnvironmentVariable("HOME") : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"); + if (homePath == null) + return string.Empty; string homeFilePath = Path.Combine(homePath, path); if (File.Exists(homeFilePath)) return homeFilePath; diff --git a/src/Hassium/Compiler/Parser/Ast/MultiAssignmentNode.cs b/src/Hassium/Compiler/Parser/Ast/MultiAssignmentNode.cs new file mode 100644 index 0000000..e116c0a --- /dev/null +++ b/src/Hassium/Compiler/Parser/Ast/MultiAssignmentNode.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hassium.Compiler.Parser.Ast +{ + public class MultiAssignmentNode: AstNode + { + public List Assignments { get; private set; } + + public MultiAssignmentNode(List left, AstNode value) + { + Assignments = new List(); + foreach (var ast in left) + Assignments.Add(new BinaryOperationNode(value.SourceLocation, BinaryOperation.Assignment, ast, value)); + } + + public override void Visit(IVisitor visitor) + { + visitor.Accept(this); + } + public override void VisitChildren(IVisitor visitor) + { + foreach (AstNode child in Children) + child.Visit(visitor); + } + } +} diff --git a/src/Hassium/Compiler/Parser/IVisitor.cs b/src/Hassium/Compiler/Parser/IVisitor.cs index b3d51c3..fe4e0ec 100755 --- a/src/Hassium/Compiler/Parser/IVisitor.cs +++ b/src/Hassium/Compiler/Parser/IVisitor.cs @@ -35,6 +35,7 @@ public interface IVisitor void Accept(LambdaNode node); void Accept(ListAccessNode node); void Accept(ListDeclarationNode node); + void Accept(MultiAssignmentNode node); void Accept(PropertyNode node); void Accept(RaiseNode node); void Accept(ReturnNode node); diff --git a/src/Hassium/Compiler/Parser/Parser.cs b/src/Hassium/Compiler/Parser/Parser.cs index 47f25d2..74d615a 100755 --- a/src/Hassium/Compiler/Parser/Parser.cs +++ b/src/Hassium/Compiler/Parser/Parser.cs @@ -260,6 +260,20 @@ private ListDeclarationNode parseListDeclaration() } return new ListDeclarationNode(Location, initial); } + private bool scanCommas = true; + private MultiAssignmentNode parseMultiAssignment() + { + List left = new List(); + scanCommas = false; + left.Add(new IdentifierNode(Location, ExpectToken(TokenType.Identifier).Value)); + while (AcceptToken(TokenType.Comma)) + left.Add(new IdentifierNode(Location, ExpectToken(TokenType.Identifier).Value)); + scanCommas = true; + ExpectToken(TokenType.Assignment); + AstNode value = parseExpression(); + value.SourceLocation = Location; + return new MultiAssignmentNode(left, value); + } private FuncParameter parseParameter() { string name = ExpectToken(TokenType.Identifier).Value; @@ -700,6 +714,8 @@ private AstNode parseTerm() return new ThreadNode(Location, AcceptToken(TokenType.Identifier, "do"), parseStatement()); else if (MatchToken(TokenType.Identifier) && Tokens[Position + 1].TokenType == TokenType.Identifier) return parseEnforcedAssignment(); + else if (MatchToken(TokenType.Identifier) && Tokens[Position + 1].TokenType == TokenType.Comma && scanCommas) + return parseMultiAssignment(); else if (MatchToken(TokenType.OpenSquare)) return parseListDeclaration(); else if (AcceptToken(TokenType.OpenBracket)) diff --git a/src/Hassium/Compiler/SemanticAnalysis/SemanticAnalyzer.cs b/src/Hassium/Compiler/SemanticAnalysis/SemanticAnalyzer.cs index 1415d87..da4f0e7 100755 --- a/src/Hassium/Compiler/SemanticAnalysis/SemanticAnalyzer.cs +++ b/src/Hassium/Compiler/SemanticAnalysis/SemanticAnalyzer.cs @@ -62,6 +62,7 @@ public void Accept(LabelNode node) {} public void Accept(LambdaNode node) {} public void Accept(ListAccessNode node) {} public void Accept(ListDeclarationNode node) {} + public void Accept(MultiAssignmentNode node) {} public void Accept(PropertyNode node) {} public void Accept(RaiseNode node) {} public void Accept(ReturnNode node) {} diff --git a/src/Hassium/Hassium.csproj b/src/Hassium/Hassium.csproj index 988ebde..e16b3ed 100644 --- a/src/Hassium/Hassium.csproj +++ b/src/Hassium/Hassium.csproj @@ -39,6 +39,7 @@ + diff --git a/src/Hassium/Runtime/Objects/HassiumFunction.cs b/src/Hassium/Runtime/Objects/HassiumFunction.cs index d846e9f..9afe8f1 100755 --- a/src/Hassium/Runtime/Objects/HassiumFunction.cs +++ b/src/Hassium/Runtime/Objects/HassiumFunction.cs @@ -1,5 +1,7 @@ using System; +using Hassium.Runtime.Objects.Types; + namespace Hassium.Runtime.Objects { @@ -23,6 +25,13 @@ public HassiumFunction(HassiumFunctionDelegate target, int[] paramLengths) ParameterLengths = paramLengths; } + public HassiumList get_parameterLengths(VirtualMachine vm, params HassiumObject[] args) + { + HassiumList result = new HassiumList(new HassiumObject[0]); + + return result; + } + public override HassiumObject Invoke(VirtualMachine vm, params HassiumObject[] args) { if (ParameterLengths[0] != -1) diff --git a/src/Hassium/Runtime/Objects/HassiumMethod.cs b/src/Hassium/Runtime/Objects/HassiumMethod.cs index 7cbbccb..3a87700 100755 --- a/src/Hassium/Runtime/Objects/HassiumMethod.cs +++ b/src/Hassium/Runtime/Objects/HassiumMethod.cs @@ -26,6 +26,7 @@ public class HassiumMethod: HassiumObject public HassiumMethod() { AddType(TypeDefinition); + AddAttribute("parameterLengths", new HassiumProperty(get_parameterLengths)); BreakLabels = new Stack(); ContinueLabels = new Stack(); @@ -34,6 +35,11 @@ public HassiumMethod() Parameters = new Dictionary(); } + public HassiumList get_parameterLengths(VirtualMachine vm, params HassiumObject[] args) + { + return new HassiumList(new HassiumObject[] { new HassiumInt(Parameters.Count) }); + } + public void Emit(SourceLocation location, InstructionType instructionType, int argument = 0) { Instructions.Add(new Instruction(location, instructionType, argument));