This commit is contained in:
Mike Nolan 2023-07-30 02:55:10 -05:00
parent 461b439d5b
commit 5fbf26d410
47 changed files with 1823 additions and 86 deletions

View File

@ -4,6 +4,10 @@
<ProjectReference Include="..\TLang.BytecodeCompiler\TLang.BytecodeCompiler.csproj" /> <ProjectReference Include="..\TLang.BytecodeCompiler\TLang.BytecodeCompiler.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>

View File

@ -1,9 +1,15 @@
using TLang.BytecodeCompiler; using TLang.BytecodeCompiler;
using TLang.Common; using TLang.Common;
using TLang.Parser; using TLang.Parser;
using TLang.Lexer;
using Newtonsoft.Json;
var ctx=Lex.GetTokensFromFile("app.tlang");
var res=Parse.ParseFromLexContext(ctx);
File.WriteAllText("ast.json",JsonConvert.SerializeObject(res,Formatting.Indented));
var res=Parse.ParseFromFiles("app.tlang");
using(var f = File.Create("app.tvm")) using(var f = File.Create("app.tvm"))
{ {
ByteCodeGenerator.GenerateToStream(res,f,new TLangVersion(1,0,0,0),new TLangVersion(1,0,0,0)); ByteCodeGenerator.GenerateToStream(res,f,new TLangVersion(1,0,0,0),new TLangVersion(1,0,0,0));

View File

@ -1 +1,4 @@
37+5; if("Demi Lovato")
{
print("Linus");
}

Binary file not shown.

65
ByteCodeTest/ast.json Normal file
View File

@ -0,0 +1,65 @@
{
"RootScope": true,
"IsSwitchScope": false,
"SwitchCondition": {
"LineInfo": null
},
"Nodes": [
{
"Condition": {
"Text": "Demi Lovato",
"LineInfo": {
"FileName": "memory.tlang",
"Line": 1,
"Column": 5,
"Position": 4
}
},
"Yes": {
"RootScope": false,
"IsSwitchScope": false,
"SwitchCondition": {
"LineInfo": null
},
"Nodes": [
{
"Arguments": [
{
"Text": "Linus",
"LineInfo": {
"FileName": "memory.tlang",
"Line": 3,
"Column": 12,
"Position": 28
}
}
],
"Name": "print",
"LineInfo": {
"FileName": "memory.tlang",
"Line": 3,
"Column": 6,
"Position": 22
}
}
],
"LineInfo": {
"FileName": "memory.tlang",
"Line": 3,
"Column": 6,
"Position": 22
}
},
"No": {
"LineInfo": null
},
"LineInfo": null
}
],
"LineInfo": {
"FileName": "memory.tlang",
"Line": 1,
"Column": 2,
"Position": 1
}
}

View File

@ -89,13 +89,14 @@ namespace TLang.BytecodeCompiler
int closure = Chunks.Count; int closure = Chunks.Count;
BytecodeChunk _chunk = new BytecodeChunk(); BytecodeChunk _chunk = new BytecodeChunk();
_chunk.Arguments = cValue.Arguments; _chunk.Arguments = cValue.Arguments;
GenerateCode(cValue.Node,_chunk,0,0,-1,-1,false);
Chunks.Add(_chunk); Chunks.Add(_chunk);
GenerateCode(cValue.Node,_chunk,0,0,-1,-1,false);
WriteBigEndianInt(strm,closure); WriteBigEndianInt(strm,closure);
} }
else else
{ {
byte c = 0b00000100; byte c = 0b00000000;
if(classEntry.Modifier == "prot") {c |= 0b00000001;} if(classEntry.Modifier == "prot") {c |= 0b00000001;}
if(classEntry.Modifier == "pub") {c |= 0b00000010;} if(classEntry.Modifier == "pub") {c |= 0b00000010;}
@ -105,9 +106,9 @@ namespace TLang.BytecodeCompiler
strm.Write(bytes,0,bytes.Length); strm.Write(bytes,0,bytes.Length);
int closure = Chunks.Count; int closure = Chunks.Count;
BytecodeChunk _chunk = new BytecodeChunk(); BytecodeChunk _chunk = new BytecodeChunk();
GenerateCode(new ReturnNode(classEntry.InitialValue),_chunk,0,0,-1,-1,false);
Chunks.Add(_chunk); Chunks.Add(_chunk);
GenerateCode(new ReturnNode(classEntry.InitialValue),_chunk,0,0,-1,-1,false);
WriteBigEndianInt(strm,closure); WriteBigEndianInt(strm,closure);
} }
} }
@ -183,8 +184,20 @@ namespace TLang.BytecodeCompiler
var getMemberNode = node as GetMemberNode; var getMemberNode = node as GetMemberNode;
var getArrayValue = node as GetArrayNode; var getArrayValue = node as GetArrayNode;
var setVariableNode = node as SetVariableNode; var setVariableNode = node as SetVariableNode;
var postFixIncrement = node as PostFixIncrementNode;
var postFixDecrement = node as PostFixDecrementNode;
if(postFixDecrement != null)
{
GenerateCode(postFixDecrement.SymbolNode,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
SetVariableNode variableNode = new SetVariableNode(postFixDecrement.SymbolNode,new SubtractNode(postFixDecrement.SymbolNode,new ConstNumberNode(1)));
GenerateCode(variableNode,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
}
if(postFixIncrement != null)
{
GenerateCode(postFixIncrement.SymbolNode,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
SetVariableNode variableNode = new SetVariableNode(postFixIncrement.SymbolNode,new AddNode(postFixIncrement.SymbolNode,new ConstNumberNode(1)));
GenerateCode(variableNode,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
}
if(scNode != null) if(scNode != null)
{ {
if(scNode.IsSwitchScope) if(scNode.IsSwitchScope)
@ -315,11 +328,11 @@ namespace TLang.BytecodeCompiler
GenerateCode(variableNode1,chunk,scopeIndex+1,0,_labelBeginningLoop,_labelEndLoop,false); GenerateCode(variableNode1,chunk,scopeIndex+1,0,_labelBeginningLoop,_labelEndLoop,false);
LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}"); LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}");
chunk.Add(labelNode); chunk.Add(labelNode);
GenerateCode(new NotNode(new MethodCallNode(variableNode,"movenext")),chunk,scopeBreakIndex+1,0,labelNum,labelNumEnd,false);
JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}"); JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}");
chunk.Add(conditional); chunk.Add(conditional);
SetVariableNode variableNode2=new SetVariableNode(eachNode.Name,new NotNode(new MethodCallNode(variableNode,"movenext"))); SetVariableNode variableNode2=new SetVariableNode(eachNode.Name,new GetMemberNode(variableNode,"current"));
GenerateCode(variableNode2,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false); GenerateCode(variableNode2,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
GenerateCode(eachNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false); GenerateCode(eachNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
@ -336,15 +349,18 @@ namespace TLang.BytecodeCompiler
chunk.Add(new SimpleInstruction(Instruction.SCOPE_BEGIN)); chunk.Add(new SimpleInstruction(Instruction.SCOPE_BEGIN));
GenerateCode(forNode.Init,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false); GenerateCode(forNode.Init,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}"); LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}");
chunk.Add(labelNode); chunk.Add(labelNode);
GenerateCode(new NotNode(forNode.Condition),chunk,scopeIndex+1,0,labelNum,labelNumEnd,false); GenerateCode(new NotNode(forNode.Condition),chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
//chunk.Add(new SimpleInstruction(Instruction.POP));
JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}"); JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}");
chunk.Add(conditional); chunk.Add(conditional);
GenerateCode(forNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false); GenerateCode(forNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
GenerateCode(forNode.Increment,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false); GenerateCode(forNode.Increment,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
JumpUnconditional juC=new JumpUnconditional($"_label{labelNum}"); JumpUnconditional juC=new JumpUnconditional($"_label{labelNum}");
chunk.Add(juC); chunk.Add(juC);
LabelInstruction endLabel = new LabelInstruction($"_label{labelNumEnd}"); LabelInstruction endLabel = new LabelInstruction($"_label{labelNumEnd}");
@ -403,9 +419,11 @@ namespace TLang.BytecodeCompiler
{ {
BytecodeChunk _chunk = new BytecodeChunk(); BytecodeChunk _chunk = new BytecodeChunk();
_chunk.Arguments = closureNode.Arguments; _chunk.Arguments = closureNode.Arguments;
int i = Chunks.Count;
Chunks.Add(_chunk);
GenerateCode(closureNode.Node,_chunk,0,0,-1,-1,false); GenerateCode(closureNode.Node,_chunk,0,0,-1,-1,false);
int i = Chunks.Count;
Chunks.Add(_chunk);
chunk.Add(new PushClosureNode(i)); chunk.Add(new PushClosureNode(i));
} }
if(node is NullNode) if(node is NullNode)

View File

@ -40,6 +40,7 @@ namespace TLang.Common
public const byte GT = 0x17; public const byte GT = 0x17;
public const byte GTE = 0x18; public const byte GTE = 0x18;
public const byte POP = 0xE9;
public const byte SCOPE_BEGIN = 0xEA; public const byte SCOPE_BEGIN = 0xEA;
public const byte SCOPE_END = 0xEB; public const byte SCOPE_END = 0xEB;

View File

@ -1,6 +1,8 @@
using System;
namespace TLang.Common namespace TLang.Common
{ {
public class TLangDependency public class TLangDependency : IEquatable<TLangDependency>
{ {
public TLangDependency(string name,TLangVersion version) public TLangDependency(string name,TLangVersion version)
{ {
@ -13,5 +15,10 @@ namespace TLang.Common
} }
public string Name {get;set;} public string Name {get;set;}
public TLangVersion Version {get;set;} public TLangVersion Version {get;set;}
public bool Equals(TLangDependency other)
{
return Name == other.Name && Version.IntegerVersion == other.Version.IntegerVersion;
}
} }
} }

View File

@ -64,10 +64,7 @@ namespace TLang.Lexer
if(interoplated) if(interoplated)
{ {
tokens.Add(LexToken.Token("String").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token(".").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token("Concat").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo));
int e = 0; int e = 0;
int escapeI = 0; int escapeI = 0;
@ -80,7 +77,7 @@ namespace TLang.Lexer
{ {
if(b2.Length > 0 && escapeI < 1) if(b2.Length > 0 && escapeI < 1)
{ {
if(e > 0) tokens.Add(LexToken.Token(",").WithLineInfo(lineInfo)); if(e > 0) tokens.Add(LexToken.Token("+").WithLineInfo(lineInfo));
tokens.Add(LexToken.String(b2.ToString()).WithLineInfo(lineInfo)); tokens.Add(LexToken.String(b2.ToString()).WithLineInfo(lineInfo));
b2.Clear(); b2.Clear();
e++; e++;
@ -104,12 +101,17 @@ namespace TLang.Lexer
escapeI--; escapeI--;
if(b2.Length > 0 && escapeI == 0) if(b2.Length > 0 && escapeI == 0)
{ {
if(e > 0) tokens.Add(LexToken.Token(",").WithLineInfo(lineInfo)); if(e > 0) tokens.Add(LexToken.Token("+").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo)); tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo));
tokens.AddRange(Lex.GetTokensFromString(b2.ToString(),"compilerGenerated.tlang").Tokens); tokens.AddRange(Lex.GetTokensFromString(b2.ToString(),"compilerGenerated.tlang").Tokens);
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo)); tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token(".").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token("toString").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
b2.Clear(); b2.Clear();
e++; e++;
} }
@ -128,18 +130,23 @@ namespace TLang.Lexer
{ {
if(escapeI > 0) if(escapeI > 0)
{ {
if(e > 0) tokens.Add(LexToken.Token(",").WithLineInfo(lineInfo)); if(e > 0) tokens.Add(LexToken.Token("+").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo)); tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo));
tokens.AddRange(Lex.GetTokensFromString(b2.ToString(),"compilerGenerated.tlang").Tokens); tokens.AddRange(Lex.GetTokensFromString(b2.ToString(),"compilerGenerated.tlang").Tokens);
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo)); tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token(".").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token("toString").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo));
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
b2.Clear(); b2.Clear();
e++; e++;
} }
else else
{ {
if(e > 0) tokens.Add(LexToken.Token(",").WithLineInfo(lineInfo)); if(e > 0) tokens.Add(LexToken.Token("+").WithLineInfo(lineInfo));
tokens.Add(LexToken.String(b2.ToString()).WithLineInfo(lineInfo)); tokens.Add(LexToken.String(b2.ToString()).WithLineInfo(lineInfo));
b2.Clear(); b2.Clear();
e++; e++;
@ -147,7 +154,7 @@ namespace TLang.Lexer
} }
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
} }
else else

View File

@ -50,6 +50,7 @@ namespace TLang.Lexer
} }
if(consumeIfTrue) Offset += tokenText.Length; if(consumeIfTrue) Offset += tokenText.Length;
return new LexEntryContext(tokens,offset,true); return new LexEntryContext(tokens,offset,true);
} }
public LexEntryContext NextEntries(bool consumeIfTrue,params string[] tokenText) public LexEntryContext NextEntries(bool consumeIfTrue,params string[] tokenText)

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using TLang.Lexer; using TLang.Lexer;
namespace TLang.Parser namespace TLang.Parser
{ {
@ -338,18 +339,63 @@ return res;
} }
return expr; return expr;
} }
private Node ParseValue() private Node ParseValue()
{ {
var doc = Context.PopDocumentation(); var doc = Context.PopDocumentation();
var token = Context.NextEntry(); var token = Context.NextEntry();
if(token.IsString) return new StringNode(token.Text){LineInfo = token.Position}; if(token.IsString) return new StringNode(token.Text){LineInfo = token.Position};
if(token.IsChar) return new CharNode(token.Text){LineInfo = token.Position}; if(token.IsChar) return new CharNode(token.Text){LineInfo = token.Position};
if(token.Text == "ensure")
{
string t = Context.NextEntry().Text;
IfNode node = new IfNode(new NotNode(new GetVariableNode(t)),new SetVariableNode(new GetVariableNode(t),new FunctionCallNode("dictionary")),new Node());
return node;
}
if(token.Text == "(") if(token.Text == "(")
{ {
var assignable = ParseAssigable(); var assignable = ParseAssigable();
assignable.LineInfo = token.Position; assignable.LineInfo = token.Position;
if(!Context.NextEntries(true,")").Success) throw new CompilerError("symbol must be a ')'",assignable); if(!Context.NextEntries(true,")").Success) throw new CompilerError("symbol must be a ')'",assignable);
while(Context.MoreTokens && Context.NextEntries(true,"[").Success)
{
var p = ParseNode();
assignable = new GetArrayNode(assignable,p){LineInfo = p.LineInfo};
Context.NextEntries(true,"]");
}
while(Context.MoreTokens && Context.NextEntries(true,".").Success)
{
var token2 = Context.NextEntry();
if(Context.MoreTokens && Context.NextEntries(true,"(").Success)
{
var mCall = new MethodCallNode(assignable,token2.Text){LineInfo=token2.Position};
assignable = mCall;
while(Context.MoreTokens && !Context.NextEntries(true,")").Success)
{
if(Context.NextEntries(true,",").Success) continue;
mCall.Arguments.Add(ParseNode());
}
}
else if(Context.MoreTokens && Context.NextEntries(false,"[").Success)
{
assignable = new GetMemberNode(assignable,token2.Text);
while(Context.MoreTokens && Context.NextEntries(true,"[").Success)
{
var p = ParseNode();
assignable = new GetArrayNode(assignable,p){LineInfo = p.LineInfo};
Context.NextEntries(true,"]");
}
}
else
{
assignable = new GetMemberNode(assignable,token2.Text){LineInfo = token2.Position};
}
}
return assignable; return assignable;
} }
if(token.Text == "class") if(token.Text == "class")
@ -606,6 +652,7 @@ return res;
} }
else if(Context.MoreTokens && Context.NextEntries(false,"[").Success) else if(Context.MoreTokens && Context.NextEntries(false,"[").Success)
{ {
ret = new GetMemberNode(ret,token2.Text);
while(Context.MoreTokens && Context.NextEntries(true,"[").Success) while(Context.MoreTokens && Context.NextEntries(true,"[").Success)
{ {
var p = ParseNode(); var p = ParseNode();
@ -616,9 +663,11 @@ return res;
else else
{ {
ret = new GetMemberNode(ret,token2.Text){LineInfo = token2.Position}; ret = new GetMemberNode(ret,token2.Text){LineInfo = token2.Position};
} }
} }
if(Context.MoreTokens && Context.NextEntries(true,"++").Success) if(Context.MoreTokens && Context.NextEntries(true,"++").Success)
{ {
var r = new PostFixIncrementNode(ret){LineInfo = ret.LineInfo}; var r = new PostFixIncrementNode(ret){LineInfo = ret.LineInfo};
@ -682,7 +731,7 @@ return res;
ret = new GetArrayNode(ret,p){LineInfo = p.LineInfo}; ret = new GetArrayNode(ret,p){LineInfo = p.LineInfo};
Context.NextEntries(true,"]"); Context.NextEntries(true,"]");
} }
while(Context.MoreTokens && Context.NextEntries(true,".").Success) while(Context.MoreTokens && Context.NextEntries(true,".").Success)
{ {
var token2 = Context.NextEntry(); var token2 = Context.NextEntry();
@ -696,8 +745,10 @@ return res;
mCall.Arguments.Add(ParseNode()); mCall.Arguments.Add(ParseNode());
} }
} }
else if(Context.MoreTokens && Context.NextEntries(false,"[").Success) else
if(Context.MoreTokens && Context.NextEntries(false,"[").Success)
{ {
ret =new GetMemberNode(ret,token2.Text);
while(Context.MoreTokens && Context.NextEntries(true,"[").Success) while(Context.MoreTokens && Context.NextEntries(true,"[").Success)
{ {
var p = ParseNode(); var p = ParseNode();
@ -708,6 +759,7 @@ return res;
else else
{ {
ret = new GetMemberNode(ret,token2.Text){LineInfo = token2.Position}; ret = new GetMemberNode(ret,token2.Text){LineInfo = token2.Position};
} }
} }

View File

@ -2,13 +2,13 @@ namespace TLang.Parser
{ {
public class GetArrayNode : SymbolNode public class GetArrayNode : SymbolNode
{ {
public SymbolNode Symbol {get;set;} public Node Symbol {get;set;}
public Node Expression {get;set;} public Node Expression {get;set;}
public GetArrayNode(SymbolNode sym, Node expr) public GetArrayNode(Node sym, Node expr)
{ {
Symbol = sym; Symbol = sym;
this.Name = sym.Name; this.Name = "";
Expression = expr; Expression = expr;
} }
} }

View File

@ -5,10 +5,10 @@ namespace TLang.Parser
{ {
public class MethodCallNode : SymbolNode public class MethodCallNode : SymbolNode
{ {
public SymbolNode Symbol {get;set;} public Node Symbol {get;set;}
public List<Node> Arguments {get;set;}=new List<Node>(); public List<Node> Arguments {get;set;}=new List<Node>();
public MethodCallNode(SymbolNode symbol, string name) public MethodCallNode(Node symbol, string name)
{ {
Symbol = symbol; Symbol = symbol;
Name = name; Name = name;

View File

@ -6,5 +6,6 @@ namespace TLang.Parser
{ {
public LexLineInfo LineInfo {get;set;} public LexLineInfo LineInfo {get;set;}
} }
} }

41
TLang.VM/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,41 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"WARNING01": "*********************************************************************************",
"WARNING02": "The C# extension was unable to automatically decode projects in the current",
"WARNING03": "workspace to create a runnable launch.json file. A template launch.json file has",
"WARNING04": "been created as a placeholder.",
"WARNING05": "",
"WARNING06": "If OmniSharp is currently unable to load your project, you can attempt to resolve",
"WARNING07": "this by restoring any missing project dependencies (example: run 'dotnet restore')",
"WARNING08": "and by fixing any reported errors from building the projects in your workspace.",
"WARNING09": "If this allows OmniSharp to now load your project then --",
"WARNING10": " * Delete this file",
"WARNING11": " * Open the Visual Studio Code command palette (View->Command Palette)",
"WARNING12": " * run the command: '.NET: Generate Assets for Build and Debug'.",
"WARNING13": "",
"WARNING14": "If your project requires a more complex launch configuration, you may wish to delete",
"WARNING15": "this configuration and pick a different template using the 'Add Configuration...'",
"WARNING16": "button at the bottom of this file.",
"WARNING17": "*********************************************************************************",
"preLaunchTask": "build",
"program": "${workspaceFolder}/../VMTest/bin/Debug/net7.0/VMTest.dll",
"args": [],
"cwd": "${workspaceFolder}/../VMTest/",
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@ -13,37 +13,44 @@ namespace TLang.VM
public override TObject GetObject(string key) public override TObject GetObject(string key)
{ {
throw new System.NotImplementedException(); if(key == "this")
{
return classInstance;
}
return oGenv.GetObject(key);
} }
public override TLangEnvironment GetParentEnvironment() public override TLangEnvironment GetParentEnvironment()
{ {
throw new System.NotImplementedException(); return oGenv;
} }
public override RootEnvironment GetRootEnvironment() public override RootEnvironment GetRootEnvironment()
{ {
throw new System.NotImplementedException(); return oGenv.GetRootEnvironment();
} }
public override TLangEnvironment GetSubEnvironment() public override TLangEnvironment GetSubEnvironment()
{ {
throw new System.NotImplementedException(); return new SubEnvironment(this);
} }
public override bool HasObject(string key) public override bool HasObject(string key)
{ {
throw new System.NotImplementedException(); if(key == "this") return true;
return oGenv.HasObject(key);
} }
public override bool HasObjectRecurse(string key) public override bool HasObjectRecurse(string key)
{ {
throw new System.NotImplementedException(); if(key == "this") return true;
return oGenv.HasObjectRecurse(key);
} }
public override void SetObject(string key, TObject value) public override void SetObject(string key, TObject value)
{ {
throw new System.NotImplementedException(); if(key == "this") return;
oGenv.SetObject(key,value);
} }
} }
} }

10
TLang.VM/ClassField.cs Normal file
View File

@ -0,0 +1,10 @@
namespace TLang.VM
{
public class ClassField
{
public bool Protected {get;set;}
public bool Private {get;set;}
public string ClassName {get;set;}
public TObject Value {get;set;}
}
}

View File

@ -2,14 +2,12 @@ namespace TLang.VM
{ {
public class ClassMethod public class ClassMethod
{ {
public bool Public {get;set;} public string ClassName {get;set;}
public bool Private {get;set;} public bool Private {get;set;}
public bool Protected {get;set;} public bool Protected {get;set;}
public Chunk Chunk {get;set;} public TCallable Closure {get;set;}
public TVMFile File {get;set;}
} }
} }

View File

@ -1,6 +1,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using TLang.Common; using TLang.Common;
namespace TLang.VM namespace TLang.VM
@ -8,14 +9,14 @@ namespace TLang.VM
public class DefaultDependencyPool : IDependencyPool public class DefaultDependencyPool : IDependencyPool
{ {
List<(TLangDependency Dependency,TVMFile File)> items = new List<(TLangDependency Dependency, TVMFile File)>(); List<(TLangDependency Dependency,TVMFile File)> items = new List<(TLangDependency Dependency, TVMFile File)>();
public bool AddDependency(TLangDependency dependency) public bool AddDependency(TLangDependency dependency,RootEnvironment env)
{ {
string fileName = $"{dependency.Name}-{dependency.Version}.tvm"; string fileName = $"{dependency.Name}-{dependency.Version}.tvm";
if(File.Exists(fileName)) if(File.Exists(fileName))
{ {
using(var f = File.OpenRead(fileName)) using(var f = File.OpenRead(fileName))
{ {
TVMFile file = new TVMFile(f); TVMFile file = new TVMFile(f,env);
items.Add((dependency,file)); items.Add((dependency,file));
return file.LoadDependencies(this); return file.LoadDependencies(this);
} }
@ -34,17 +35,19 @@ namespace TLang.VM
public bool DependencyExists(TLangDependency dependency) public bool DependencyExists(TLangDependency dependency)
{ {
throw new System.NotImplementedException(); return items.Any(e=>
e.Dependency.Equals(dependency)
);
} }
public IEnumerator<(TLangDependency Dependency, TVMFile File)> GetEnumerator() public IEnumerator<(TLangDependency Dependency, TVMFile File)> GetEnumerator()
{ {
throw new System.NotImplementedException(); return items.GetEnumerator();
} }
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
throw new System.NotImplementedException(); return this.GetEnumerator();
} }
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
namespace TLang.VM namespace TLang.VM
{ {
@ -7,7 +8,7 @@ namespace TLang.VM
{ {
public RootEnvironment() public RootEnvironment()
{ {
} }
public Dictionary<string, LoadedClassData> AvailableClasses {get;set;}=new Dictionary<string, LoadedClassData>(); public Dictionary<string, LoadedClassData> AvailableClasses {get;set;}=new Dictionary<string, LoadedClassData>();
@ -48,5 +49,128 @@ namespace TLang.VM
{ {
return new SubEnvironment(this); return new SubEnvironment(this);
} }
public void LoadStd()
{
SetObject("array",new TExternalMethod((e)=>{
TArray array=new TArray();
if(e.Length > 0)
{
var n = e[0] as TNumber;
if(n != null) array.Items=new List<TObject>((int)n.Value);
}
return array;
}));
SetObject("arrayof",new TExternalMethod((e)=>{
TArray array=new TArray();
foreach(var item in e) array.Add(item);
return array;
}));
SetObject("dictionary",new TExternalMethod(e=>{
return new TDictionary();
}));
SetObject("toNumber",new TExternalMethod(e=>{
if(double.TryParse(e[0].ToString(),out var res))
{
return new TNumber(res);
}
return new TNumber(0);
}));
SetObject("typeof",new TExternalMethod(e=>{
if(e.Length > 0)
{
return new TString(e[0].Type);
}
return new TString("");
}));
SetObject("con",Con());
SetObject("fs",Filesystem());
}
private TObject Con()
{
TDictionary con=new TDictionary();
con.SetValue("println",new TExternalMethod((e)=>{
Console.WriteLine(e[0].ToString());
return new TNull();
}));
con. SetValue("print",new TExternalMethod((e)=>{
Console.Write(e[0].ToString());
return new TNull();
}));
con.SetValue("readln",new TExternalMethod((e)=>{
return new TString(Console.ReadLine());
}));
return con;
}
private TObject Filesystem()
{
TDictionary fs=new TDictionary();
fs.SetValue("mkdir",new TExternalMethod((e)=>{
if(e.Length > 0)
{
return new TBool(Directory.CreateDirectory(e[0].ToString()).Exists);
}
return new TBool(false);
}));
fs.SetValue("directoryExists",new TExternalMethod((e)=>{
if(e.Length > 0)
{
return new TBool(Directory.Exists(e[0].ToString()));
}
return new TBool(false);
}));
fs.SetValue("fileExists",new TExternalMethod((e)=>{
if(e.Length > 0)
{
return new TBool(File.Exists(e[0].ToString()));
}
return new TBool(false);
}));
fs.SetValue("readAllText",new TExternalMethod((e)=>{
if(e.Length > 0)
{
return new TString(File.ReadAllText(e[0].ToString()));
}
return new TNull();
}));
fs.SetValue("writeAllText",new TExternalMethod((e)=>{
if(e.Length > 1)
{
File.WriteAllText(e[0].ToString(),e[1].ToString());
}
return new TNull();
}));
fs.SetValue("getFiles",new TExternalMethod((e)=>{
TArray array=new TArray();
if(e.Length > 0)
{
foreach(var item in Directory.GetFiles(e[0].ToString()))
{
array.Items.Add(new TString(Path.GetFileName(item)));
}
}
return array;
}));
fs.SetValue("getDirectories",new TExternalMethod((e)=>{
TArray array=new TArray();
if(e.Length > 0)
{
foreach(var item in Directory.GetDirectories(e[0].ToString()))
{
array.Items.Add(new TString(Path.GetFileName(item)));
}
}
return array;
}));
return fs;
}
} }
} }

View File

@ -31,7 +31,7 @@ namespace TLang.VM
} }
public override bool HasObjectRecurse(string key) public override bool HasObjectRecurse(string key)
{ {
return HasObject(key) && pEnv.HasObjectRecurse(key); return HasObject(key) || pEnv.HasObjectRecurse(key);
} }

20
TLang.VM/TArray.cs Normal file
View File

@ -0,0 +1,20 @@
using System.Collections.Generic;
namespace TLang.VM
{
public class TArray : TObject
{
public override string Type => "array";
public List<TObject> Items {get;set;}=new List<TObject>();
public override bool True => Items.Count > 0;
public void Add(TObject value)
{
Items.Add(value);
}
public void Remove(TObject value)
{
Items.Remove(value);
}
}
}

18
TLang.VM/TBool.cs Normal file
View File

@ -0,0 +1,18 @@
namespace TLang.VM
{
public class TBool : TObject
{
public override string Type => "bool";
public override bool True => Value;
public bool Value {get;set;}
public TBool(bool value)
{
Value = value;
}
public override string ToString()
{
return Value ? "true" : "false";
}
}
}

View File

@ -2,6 +2,9 @@ namespace TLang.VM
{ {
public abstract class TCallable : TObject public abstract class TCallable : TObject
{ {
public string ClassName {get;set;}
public override string Type => "function";
public override bool True => true;
public abstract TObject Execute(params TObject[] args); public abstract TObject Execute(params TObject[] args);
} }
} }

18
TLang.VM/TChar.cs Normal file
View File

@ -0,0 +1,18 @@
namespace TLang.VM
{
public class TChar : TObject
{
public override string Type => "char";
public override bool True => true;
public char Value {get;set;}
public TChar(char value)
{
Value = value;
}
public override string ToString()
{
return Value.ToString();
}
}
}

View File

@ -5,6 +5,8 @@ namespace TLang.VM
{ {
public class TClassInstance : TObject public class TClassInstance : TObject
{ {
public override string Type => $"class {classEntry.Name} : {classEntry.InheritsFrom}";
public override bool True => true;
TVMFile file; TVMFile file;
Class classEntry; Class classEntry;
TLangEnvironment oGenv; TLangEnvironment oGenv;
@ -17,6 +19,8 @@ namespace TLang.VM
public List<string> InheritenceTree {get;}=new List<string>(); public List<string> InheritenceTree {get;}=new List<string>();
public Dictionary<string,ClassMethod> Methods {get;} = new Dictionary<string, ClassMethod>(); public Dictionary<string,ClassMethod> Methods {get;} = new Dictionary<string, ClassMethod>();
public Dictionary<string,ClassField> Fields {get;} = new Dictionary<string, ClassField>();
public void Init(params TObject[] args) public void Init(params TObject[] args)
@ -25,12 +29,34 @@ namespace TLang.VM
foreach(var item in classEntry.ClassEntries) foreach(var item in classEntry.ClassEntries)
{ {
if(item.Method)
{
ClassMethod meth=new ClassMethod();
TClosure closure=new TClosure(file,file.Chunks[item.ChunkId],Environment);
meth.Private = item.Private;
meth.Protected = item.Protected;
meth.Closure = closure;
meth.ClassName = classEntry.Name;
Methods.Add(item.Name,meth);
}
else
{
ClassField field = new ClassField();
field.ClassName = classEntry.Name;
TClosure closure = new TClosure(file,file.Chunks[item.ChunkId],Environment);
field.Private = item.Private;
field.Protected = item.Protected;
field.Value = closure.Execute();
Fields.Add(item.Name,field);
}
} }
var cE = classEntry; var cE = classEntry;
var aC =oGenv.GetRootEnvironment().AvailableClasses; var aC =oGenv.GetRootEnvironment().AvailableClasses;
//we need to check inheritence //we need to check inheritence
while(cE.InheritsFrom != "object") while(cE.InheritsFrom != "object" && cE.InheritsFrom != "")
{ {
InheritenceTree.Add(cE.InheritsFrom); InheritenceTree.Add(cE.InheritsFrom);
if(aC.ContainsKey(cE.InheritsFrom)) if(aC.ContainsKey(cE.InheritsFrom))
@ -39,43 +65,104 @@ namespace TLang.VM
cE = aC2.ToClass(cE.InheritsFrom); cE = aC2.ToClass(cE.InheritsFrom);
foreach(var item in cE.ClassEntries) foreach(var item in cE.ClassEntries)
{ {
if(!Fields.ContainsKey(item.Name) && !item.Method)
{
ClassField field = new ClassField();
field.ClassName = cE.Name;
TClosure closure = new TClosure(aC2.File,aC2.File.Chunks[item.ChunkId],Environment);
field.Private = item.Private;
field.Protected = item.Protected;
field.Value = closure.Execute();
Fields.Add(item.Name,field);
}
if(!Methods.ContainsKey(item.Name) && item.Method) if(!Methods.ContainsKey(item.Name) && item.Method)
{ {
if(item.Abstract) throw new Exception("Method is abstract"); if(item.Abstract) throw new Exception("Method is abstract");
ClassMethod meth=new ClassMethod(); ClassMethod meth=new ClassMethod();
meth.File = aC2.File; TClosure closure=new TClosure(aC2.File,aC2.File.Chunks[item.ChunkId],Environment);
meth.Chunk = aC2.File.Chunks[item.ChunkId]; meth.ClassName = cE.Name;
meth.Closure = closure;
meth.Private = item.Private; meth.Private = item.Private;
meth.Protected = item.Protected; meth.Protected = item.Protected;
meth.Public = item.Public;
Methods.Add(item.Name,meth); Methods.Add(item.Name,meth);
} }
} }
} }
} }
if(!Methods.ContainsKey("toString"))
{
Methods.Add("toString",new ClassMethod(){ClassName="object", Closure = new TExternalMethod(e=>new TString($"class {classEntry.Name} : {classEntry.InheritsFrom}")), Private=false, Protected = false});
}
if(Methods.ContainsKey(classEntry.Name))
{
var ctor=Methods[classEntry.Name];
if(ctor.ClassName == classEntry.Name)
{
ctor.Closure.ClassName = classEntry.Name;
ctor.Closure.Execute(args);
}
}
} }
public TLangEnvironment Environment {get; private set;} public TLangEnvironment Environment {get; private set;}
public void SetField(bool inside,string className,string key,TObject obj) public void SetField(string className,string key,TObject obj)
{ {
if(Fields.ContainsKey(key))
{
var field=Fields[key];
if(field.Private && className != classEntry.Name) return;
if(field.Protected && className != classEntry.Name && !InheritenceTree.Contains(className)) return;
field.Value=obj;
}
} }
public TObject GetField(string className,string key) public TObject GetField(string className,string key)
{ {
if(Fields.ContainsKey(key))
{
var field=Fields[key];
if(field.Private && className != classEntry.Name) return new TUndefined();
if(field.Protected && className != classEntry.Name && !InheritenceTree.Contains(className)) return new TUndefined();
return field.Value;
}
return new TUndefined(); return new TUndefined();
} }
public bool MethodExists(string className,string key)
{
if(Methods.ContainsKey(key))
{
var method=Methods[key];
if(method.Private && className != classEntry.Name) return false;
if(method.Protected && className != classEntry.Name && !InheritenceTree.Contains(className)) return false;
return true;
}
return false;
}
public TObject CallMethod(string className,string key,params TObject[] args) public TObject CallMethod(string className,string key,params TObject[] args)
{ {
if(Methods.ContainsKey(key)) if(Methods.ContainsKey(key))
{ {
var method=Methods[key]; var method=Methods[key];
if(method.Private && className != classEntry.Name) return new TUndefined(); if(method.Private && className != classEntry.Name) return new TUndefined();
if(method.Protected && className != classEntry.Name && !InheritenceTree.Contains(className)) return new TUndefined();
method.Closure.ClassName = method.ClassName;
return method.Closure.Execute(args);
} }
return new TUndefined(); return new TUndefined();
} }
public override string ToString()
{
return CallMethod(classEntry.Name,"toString").ToString();
}
} }
} }

View File

@ -2,6 +2,7 @@ namespace TLang.VM
{ {
public class TClosure : TCallable public class TClosure : TCallable
{ {
private TVMFile file; private TVMFile file;
private Chunk chunk; private Chunk chunk;
private TLangEnvironment env; private TLangEnvironment env;
@ -16,6 +17,7 @@ namespace TLang.VM
public override TObject Execute(params TObject[] args) public override TObject Execute(params TObject[] args)
{ {
ChunkExecuter executer = new ChunkExecuter(file,chunk,env); ChunkExecuter executer = new ChunkExecuter(file,chunk,env);
executer.ClassName=ClassName;
return executer.Execute(args); return executer.Execute(args);
} }
} }

50
TLang.VM/TDictionary.cs Normal file
View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
namespace TLang.VM
{
public class TDictionary : TObject
{
public override string Type => "dictonary";
public override bool True => true;
public Dictionary<string,TObject> Items{get;}=new Dictionary<string, TObject>();
public void SetValue(string key,TObject value)
{
Items[key] = value;
}
public TObject GetValue(string key)
{
if(Items.ContainsKey(key)) return Items[key];
return new TUndefined();
}
public bool HasValue(string key)
{
return Items.ContainsKey(key);
}
public static TDictionary FromIEnumerator(IEnumerator<TObject> enumerator)
{
TDictionary dictionary=new TDictionary();
dictionary.SetValue("movenext",new TExternalMethod(e=>{
return new TBool(enumerator.MoveNext());
}));
dictionary.SetValue("reset",new TExternalMethod(e=>{
try{
enumerator.Reset();
}catch(Exception ex)
{
_=ex;
return new TBool(false);
}
return new TBool(true);
}));
dictionary.SetValue("getcurrent",new TExternalMethod(e=>{
return enumerator.Current;
}));
return dictionary;
}
}
}

View File

@ -0,0 +1,20 @@
using System;
namespace TLang.VM
{
internal class TExternalMethod : TCallable
{
public Func<TObject[], TObject> Callback {get;set;}
public TExternalMethod(Func<TObject[], TObject> value)
{
Callback = (args)=>{
return value(args);
};
}
public override TObject Execute(params TObject[] args)
{
return Callback(args);
}
}
}

View File

@ -2,5 +2,11 @@ namespace TLang.VM
{ {
public class TNull : TObject public class TNull : TObject
{ {
public override string Type => "null";
public override bool True => false;
public override string ToString()
{
return "null";
}
} }
} }

View File

@ -2,11 +2,17 @@ namespace TLang.VM
{ {
public class TNumber : TObject public class TNumber : TObject
{ {
public override string Type => "number";
public override bool True => Value != 0;
public double Value {get;set;} public double Value {get;set;}
public TNumber(double value) public TNumber(double value)
{ {
this.Value = value; this.Value = value;
} }
public override string ToString()
{
return Value.ToString();
}
} }
} }

View File

@ -1,6 +1,8 @@
namespace TLang.VM namespace TLang.VM
{ {
public class TObject public abstract class TObject
{ {
public abstract string Type {get;}
public abstract bool True { get; }
} }
} }

View File

@ -1,12 +1,34 @@
using System.Collections.Generic;
namespace TLang.VM namespace TLang.VM
{ {
public class TString : TObject public class TString : TObject
{ {
public override string Type => "string";
public override bool True => !string.IsNullOrWhiteSpace(Value);
public string Value {get;set;} public string Value {get;set;}
public IEnumerable<TObject> GetObjects()
{
foreach(var item in Value)
{
yield return new TChar(item);
}
}
public IEnumerable<TObject> GetChars()
{
foreach(var item in Value)
{
yield return new TChar(item);
}
}
public TString(string value) public TString(string value)
{ {
this.Value = value; this.Value = value;
} }
public override string ToString()
{
return Value;
}
} }
} }

View File

@ -2,5 +2,11 @@ namespace TLang.VM
{ {
public class TUndefined : TObject public class TUndefined : TObject
{ {
public override string Type => "undefined";
public override bool True => false;
public override string ToString()
{
return "undefined";
}
} }
} }

View File

@ -14,6 +14,8 @@ namespace TLang.VM
public List<Chunk> Chunks {get;set;}=new List<Chunk>(); public List<Chunk> Chunks {get;set;}=new List<Chunk>();
public TLangVersion Version {get;set;} public TLangVersion Version {get;set;}
public RootEnvironment Environment {get;private set;} public RootEnvironment Environment {get;private set;}
public ChunkExecuter DefaultChunkExecuter => new ChunkExecuter(this,Chunks[0],Environment);
public TVMFile(Stream file,RootEnvironment env) public TVMFile(Stream file,RootEnvironment env)
{ {
Environment = env; Environment = env;
@ -141,6 +143,11 @@ namespace TLang.VM
foreach(var class0 in Classes) foreach(var class0 in Classes)
{ {
Environment.AvailableClasses.Add(class0.Name,new LoadedClassData(class0.InheritsFrom,this,class0.ClassEntries)); Environment.AvailableClasses.Add(class0.Name,new LoadedClassData(class0.InheritsFrom,this,class0.ClassEntries));
Environment.SetObject(class0.Name,new TExternalMethod(args=>{
TClassInstance instance = new TClassInstance(this,class0,Environment);
instance.Init(args);
return instance;
}));
} }
return true; return true;

26
TLangScriptRunner/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net7.0/TLangScriptRunner.dll",
"args": ["${workspaceFolder}/fstest.tlang"],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

41
TLangScriptRunner/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/TLangScriptRunner.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/TLangScriptRunner.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/TLangScriptRunner.csproj"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -0,0 +1,14 @@
using TLang.VM;
using TLang.BytecodeCompiler;
using TLang.Parser;
using TLang.Common;
var node=Parse.ParseFromFiles(args);
MemoryStream memoryStream=new MemoryStream();
ByteCodeGenerator.GenerateToStream(node,memoryStream,TLangVersion.Version,new TLangVersion(1,0,0,0));
memoryStream.Position=0;
RootEnvironment environment=new RootEnvironment();
environment.LoadStd();
TVMFile file=new TVMFile(memoryStream,environment);
file.LoadDependencies(new DefaultDependencyPool());
file.DefaultChunkExecuter.Execute();

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\TLang.BytecodeCompiler\TLang.BytecodeCompiler.csproj" />
<ProjectReference Include="..\TLang.VM\TLang.VM.csproj" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1 @@
Demi Lovato

View File

@ -0,0 +1,4 @@
ensure Api;
con.println(typeof(Api));

View File

View File

@ -0,0 +1,16 @@
print("Please say your age: ");
i = toNumber(readln());
if(i < 18)
{
if(i < 13)
println("You are a preteen");
else
println("You are a teenager");
}
else
{
if(i < 20)
println("You are an adult, but are still a teenager");
else
println("You are an adult");
}

BIN
TVMTest Normal file

Binary file not shown.

View File

@ -1,10 +1,11 @@
using TLang.VM; using TLang.VM;
using var f = File.OpenRead("app.tvm"); using var f = File.OpenRead("app.tvm");
TVMFile file = new TVMFile(f); var env=new RootEnvironment();
TVMFile file = new TVMFile(f,env);
ChunkExecuter executer=new ChunkExecuter(file,file.Chunks[0],new RootEnvironment()); file.LoadDependencies(new DefaultDependencyPool());
ChunkExecuter executer=new ChunkExecuter(file,file.Chunks[0],env);
var res=executer.Execute() as TNumber; var res=executer.Execute() as TNumber;
if(res != null) if(res != null)
{ {
Console.WriteLine($"Number: {res.Value}"); Console.WriteLine($"Number: {res.Value}");
} }

Binary file not shown.