Skip to content

Commit

Permalink
Added thread expression with syntax thread { #body }
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobMisirian committed Aug 26, 2016
1 parent 18c1753 commit 1ca3147
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 41 deletions.
11 changes: 11 additions & 0 deletions src/Hassium/Compiler/CodeGen/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,17 @@ public void Accept(TernaryOperationNode node)
node.FalseStatement.Visit(this);
method.EmitLabel(node.SourceLocation, endLabel);
}
public void Accept(ThreadNode node)
{
var temp = method;
method = new HassiumMethod();
method.Name = "thread";
node.Body.Visit(this);
if (!module.ObjectPool.ContainsKey(method.GetHashCode()))
module.ObjectPool.Add(method.GetHashCode(), method);
temp.Emit(node.SourceLocation, InstructionType.BuildThread, method.GetHashCode());
method = temp;
}
public void Accept(TraitNode node)
{
int hash = node.Name.GetHashCode();
Expand Down
1 change: 1 addition & 0 deletions src/Hassium/Compiler/CodeGen/InstructionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public enum InstructionType
BuildDictionary,
BuildKeyValuePair,
BuildList,
BuildThread,
BuildTuple,
Call,
Dereference,
Expand Down
26 changes: 26 additions & 0 deletions src/Hassium/Compiler/Parser/Ast/ThreadNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;

namespace Hassium.Compiler.Parser.Ast
{
public class ThreadNode: AstNode
{
public AstNode Body { get { return Children[0]; } }

public ThreadNode(SourceLocation location, AstNode body)
{
this.SourceLocation = location;
Children.Add(body);
}

public override void Visit(IVisitor visitor)
{
visitor.Accept(this);
}
public override void VisitChildren(IVisitor visitor)
{
foreach (AstNode child in Children)
child.Visit(visitor);
}
}
}

1 change: 1 addition & 0 deletions src/Hassium/Compiler/Parser/IVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public interface IVisitor
void Accept(StringNode node);
void Accept(SwitchNode node);
void Accept(TernaryOperationNode node);
void Accept(ThreadNode node);
void Accept(TraitNode node);
void Accept(TryCatchNode node);
void Accept(TupleNode node);
Expand Down
4 changes: 3 additions & 1 deletion src/Hassium/Compiler/Parser/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private AstNode parseStatement()
block.Children.Add(parseStatement());
return block;
}
else if (MatchToken(TokenType.Identifier) && Tokens[Position + 1].TokenType == TokenType.OpenBracket)
else if (MatchToken(TokenType.Identifier) && !MatchToken(TokenType.Identifier, "thread") && Tokens[Position + 1].TokenType == TokenType.OpenBracket)
return parseProperty();
else if (MatchToken(TokenType.Identifier) && Tokens[Position + 1].TokenType == TokenType.Identifier)
return parseEnforcedAssignment();
Expand Down Expand Up @@ -621,6 +621,8 @@ private AstNode parseTerm()
return parseExpression();
else if (MatchToken(TokenType.Identifier, "lambda"))
return parseLambda();
else if (AcceptToken(TokenType.Identifier, "thread"))
return new ThreadNode(Location, parseStatement());
else if (MatchToken(TokenType.OpenSquare))
return parseListDeclaration();
else if (AcceptToken(TokenType.OpenBracket))
Expand Down
1 change: 1 addition & 0 deletions src/Hassium/Compiler/SemanticAnalysis/SemanticAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public void Accept(StatementNode node) {}
public void Accept(StringNode node) {}
public void Accept(SwitchNode node) {}
public void Accept(TernaryOperationNode node) {}
public void Accept(ThreadNode node) {}
public void Accept(TraitNode node) {}
public void Accept(TryCatchNode node) {}
public void Accept(TupleNode node) {}
Expand Down
3 changes: 3 additions & 0 deletions src/Hassium/Hassium.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@
<Compile Include="Runtime\Objects\Util\HassiumDateTime.cs" />
<Compile Include="Runtime\Objects\Types\HassiumBitArray.cs" />
<Compile Include="Compiler\Parser\Ast\EnforcedAssignmentNode.cs" />
<Compile Include="Compiler\Parser\Ast\ThreadNode.cs" />
<Compile Include="Runtime\Objects\Types\HassiumThread.cs" />
<Compile Include="Runtime\VirtualMachineContext.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
Expand Down
84 changes: 51 additions & 33 deletions src/Hassium/Runtime/Objects/HassiumMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,46 +48,64 @@ public void EmitLabel(SourceLocation location, int label)
// Instructions.Add(new Instruction(location, InstructionType.Label, label));
}

public HassiumObject Invoke(VirtualMachine vm, StackFrame.Frame frame)
{
vm.StackFrame.Frames.Push(frame);
return Invoke(vm);
}

public override HassiumObject Invoke(VirtualMachine vm, params HassiumObject[] args)
{
if (Name != "lambda" && Name != "catch") vm.StackFrame.PushFrame();
vm.CallStack.Push(SourceRepresentation);
int i = 0;
foreach (var param in Parameters)
{
var arg = args[i++];
if (param.Key.IsEnforced)
if (!arg.Types.Contains((HassiumTypeDefinition)vm.Globals[param.Key.Type].Type()))
throw new InternalException(vm, InternalException.PARAMETER_ERROR, param.Key.Type, arg.Type());
vm.StackFrame.Add(param.Value, arg);
}
if (IsConstructor)
{
HassiumClass ret = new HassiumClass();
ret.Attributes = CloneDictionary(Parent.Attributes);
foreach (var type in Parent.Types)
ret.AddType(type);
foreach (var attrib in ret.Attributes.Values)
attrib.Parent = ret;
vm.ExecuteMethod(ret.Attributes["new"] as HassiumMethod);
vm.StackFrame.PopFrame();
vm.CallStack.Pop();
return ret;
}
else
try
{
var val = vm.ExecuteMethod(this);
if (Name == "catch")
if (Name != "lambda" && Name != "catch" && Name != "thread") vm.StackFrame.PushFrame();
vm.CallStack.Push(SourceRepresentation);
int i = 0;
foreach (var param in Parameters)
{
var arg = args[i++];
if (param.Key.IsEnforced)
if (!arg.Types.Contains((HassiumTypeDefinition)vm.Globals[param.Key.Type].Type()))
throw new InternalException(vm, InternalException.PARAMETER_ERROR, param.Key.Type, arg.Type());
vm.StackFrame.Add(param.Value, arg);
}
if (IsConstructor)
{
HassiumClass ret = new HassiumClass();
ret.Attributes = CloneDictionary(Parent.Attributes);
foreach (var type in Parent.Types)
ret.AddType(type);
foreach (var attrib in ret.Attributes.Values)
attrib.Parent = ret;
vm.ExecuteMethod(ret.Attributes["new"] as HassiumMethod);
vm.StackFrame.PopFrame();
vm.CallStack.Pop();
return ret;
}
else
{
var val = vm.ExecuteMethod(this);
if (Name == "catch")
{
vm.CallStack.Pop();
return val;
}
if (ReturnType != "" && ReturnType != null)
if (val.Type() != vm.Globals[ReturnType])
throw new InternalException(vm, InternalException.RETURN_ERROR, ReturnType, val.Type());
if (Name != "lambda") vm.StackFrame.PopFrame();
vm.CallStack.Pop();
return val;
}
if (ReturnType != "" && ReturnType != null)
if (val.Type() != vm.Globals[ReturnType])
throw new InternalException(vm, InternalException.RETURN_ERROR, ReturnType, val.Type());
if (Name != "lambda") vm.StackFrame.PopFrame();
vm.CallStack.Pop();
return val;
}
catch (InternalException ex)
{
Console.WriteLine("At location {0}:", ex.VM.CurrentSourceLocation);
Console.WriteLine("{0} at:", ex.Message);
while (ex.VM.CallStack.Count > 0)
Console.WriteLine(ex.VM.CallStack.Pop());
Environment.Exit(0);
return null;
}
}

Expand Down
43 changes: 43 additions & 0 deletions src/Hassium/Runtime/Objects/Types/HassiumThread.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Threading;

namespace Hassium.Runtime.Objects.Types
{
public class HassiumThread: HassiumObject
{
public static new HassiumTypeDefinition TypeDefinition = new HassiumTypeDefinition("thread");

public Thread Thread { get; private set; }

public HassiumThread(VirtualMachine vm, HassiumMethod method, StackFrame.Frame frame)
{
VirtualMachine newVM = vm.Clone() as VirtualMachine;
newVM.ExceptionReturns = new Dictionary<HassiumMethod, int>();
newVM.Handlers = new Stack<HassiumExceptionHandler>();
newVM.Stack = new Stack<HassiumObject>();
newVM.StackFrame = new StackFrame();
Thread = new Thread(() => method.Invoke(newVM, frame));

AddType(TypeDefinition);
AddAttribute("isAlive", new HassiumProperty(get_isAlive));
AddAttribute("start", start, 0);
AddAttribute("stop", stop, 0);
}

public HassiumBool get_isAlive(VirtualMachine vm, params HassiumObject[] args)
{
return new HassiumBool(Thread.IsAlive);
}
public HassiumNull start(VirtualMachine vm, params HassiumObject[] args)
{
Thread.Start();
return HassiumObject.Null;
}
public HassiumNull stop(VirtualMachine vm, params HassiumObject[] args)
{
Thread.Abort();
return HassiumObject.Null;
}
}
}
3 changes: 2 additions & 1 deletion src/Hassium/Runtime/Objects/Types/HassiumTypesModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ public HassiumTypesModule() : base("types")
AddAttribute("keyValuePair", HassiumKeyValuePair.TypeDefinition);
AddAttribute("int", HassiumInt.TypeDefinition);
AddAttribute("list", HassiumList.TypeDefinition);
AddAttribute("null", HassiumObject.Null);
AddAttribute("object", HassiumObject.TypeDefinition);
AddAttribute("property", HassiumProperty.TypeDefinition);
AddAttribute("null", HassiumObject.Null);
AddAttribute("string", HassiumString.TypeDefinition);
AddAttribute("thread", HassiumThread.TypeDefinition);
AddAttribute("trait", HassiumTrait.TypeDefinition);
AddAttribute("TypeDefinition", HassiumTypeDefinition.TypeDefinition);
}
Expand Down
6 changes: 5 additions & 1 deletion src/Hassium/Runtime/StackFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Hassium.Runtime
{
public class StackFrame
{
public class Frame
public class Frame : ICloneable
{
public Dictionary<int, HassiumObject> variables = new Dictionary<int, HassiumObject>();
public void Add(int index, HassiumObject value)
Expand All @@ -26,6 +26,10 @@ public HassiumObject GetVariable(int index)
{
return variables[index];
}
public object Clone()
{
return this.MemberwiseClone();
}
}
public Stack<Frame> Frames;
public Dictionary<int, HassiumObject> Locals { get { return Frames.Peek().variables; } }
Expand Down
18 changes: 13 additions & 5 deletions src/Hassium/Runtime/VirtualMachine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@

namespace Hassium.Runtime
{
public class VirtualMachine
public class VirtualMachine : ICloneable
{
public Stack<string> CallStack { get; private set; }
public HassiumMethod CurrentMethod { get; private set; }
public HassiumModule CurrentModule { get; private set; }
public SourceLocation CurrentSourceLocation { get; private set; }
public Dictionary<HassiumMethod, int> ExceptionReturns { get; private set; }
public Dictionary<HassiumMethod, int> ExceptionReturns { get; set; }
public Dictionary<string, HassiumObject> Globals { get; private set; }
public Stack<HassiumExceptionHandler> Handlers { get; private set; }
public Stack<HassiumObject> Stack { get; private set; }
public StackFrame StackFrame { get; private set; }
public Stack<HassiumExceptionHandler> Handlers { get; set; }
public Stack<HassiumObject> Stack { get; set; }
public StackFrame StackFrame { get; set; }

public void Execute(HassiumModule module, string[] args)
{
Expand Down Expand Up @@ -86,6 +86,9 @@ public HassiumObject ExecuteMethod(HassiumMethod method)
elements[i] = Stack.Pop();
Stack.Push(new HassiumList(elements));
break;
case InstructionType.BuildThread:
Stack.Push(new HassiumThread(this, CurrentModule.ObjectPool[arg] as HassiumMethod, StackFrame.Frames.Peek()));
break;
case InstructionType.BuildTuple:
HassiumObject[] tupleElements = new HassiumObject[arg];
for (int i = 0; i < arg; i++)
Expand Down Expand Up @@ -420,5 +423,10 @@ private void importInitials()
foreach (var pair in CurrentModule.InitialVariables)
CurrentModule.Globals.Add(pair.Key, pair.Value.Invoke(this));
}

public object Clone()
{
return this.MemberwiseClone();
}
}
}
13 changes: 13 additions & 0 deletions src/Hassium/Runtime/VirtualMachineContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;

namespace Hassium.Runtime
{
public class VirtualMachineContext
{
public VirtualMachineContext()
{
}
}
}

0 comments on commit 1ca3147

Please sign in to comment.