VM works
This commit is contained in:
parent
461b439d5b
commit
5fbf26d410
|
@ -4,6 +4,10 @@
|
|||
<ProjectReference Include="..\TLang.BytecodeCompiler\TLang.BytecodeCompiler.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
using TLang.BytecodeCompiler;
|
||||
using TLang.Common;
|
||||
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"))
|
||||
{
|
||||
ByteCodeGenerator.GenerateToStream(res,f,new TLangVersion(1,0,0,0),new TLangVersion(1,0,0,0));
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
37+5;
|
||||
if("Demi Lovato")
|
||||
{
|
||||
print("Linus");
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -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
|
||||
}
|
||||
}
|
|
@ -89,13 +89,14 @@ namespace TLang.BytecodeCompiler
|
|||
int closure = Chunks.Count;
|
||||
BytecodeChunk _chunk = new BytecodeChunk();
|
||||
_chunk.Arguments = cValue.Arguments;
|
||||
GenerateCode(cValue.Node,_chunk,0,0,-1,-1,false);
|
||||
Chunks.Add(_chunk);
|
||||
GenerateCode(cValue.Node,_chunk,0,0,-1,-1,false);
|
||||
|
||||
WriteBigEndianInt(strm,closure);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte c = 0b00000100;
|
||||
byte c = 0b00000000;
|
||||
|
||||
if(classEntry.Modifier == "prot") {c |= 0b00000001;}
|
||||
if(classEntry.Modifier == "pub") {c |= 0b00000010;}
|
||||
|
@ -105,9 +106,9 @@ namespace TLang.BytecodeCompiler
|
|||
strm.Write(bytes,0,bytes.Length);
|
||||
int closure = Chunks.Count;
|
||||
BytecodeChunk _chunk = new BytecodeChunk();
|
||||
|
||||
GenerateCode(new ReturnNode(classEntry.InitialValue),_chunk,0,0,-1,-1,false);
|
||||
Chunks.Add(_chunk);
|
||||
GenerateCode(new ReturnNode(classEntry.InitialValue),_chunk,0,0,-1,-1,false);
|
||||
|
||||
WriteBigEndianInt(strm,closure);
|
||||
}
|
||||
}
|
||||
|
@ -183,8 +184,20 @@ namespace TLang.BytecodeCompiler
|
|||
var getMemberNode = node as GetMemberNode;
|
||||
var getArrayValue = node as GetArrayNode;
|
||||
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.IsSwitchScope)
|
||||
|
@ -315,11 +328,11 @@ namespace TLang.BytecodeCompiler
|
|||
GenerateCode(variableNode1,chunk,scopeIndex+1,0,_labelBeginningLoop,_labelEndLoop,false);
|
||||
LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}");
|
||||
chunk.Add(labelNode);
|
||||
|
||||
GenerateCode(new NotNode(new MethodCallNode(variableNode,"movenext")),chunk,scopeBreakIndex+1,0,labelNum,labelNumEnd,false);
|
||||
JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}");
|
||||
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(eachNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
|
||||
|
||||
|
@ -336,15 +349,18 @@ namespace TLang.BytecodeCompiler
|
|||
|
||||
chunk.Add(new SimpleInstruction(Instruction.SCOPE_BEGIN));
|
||||
GenerateCode(forNode.Init,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
|
||||
|
||||
LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}");
|
||||
chunk.Add(labelNode);
|
||||
|
||||
GenerateCode(new NotNode(forNode.Condition),chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
|
||||
//chunk.Add(new SimpleInstruction(Instruction.POP));
|
||||
JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}");
|
||||
chunk.Add(conditional);
|
||||
|
||||
GenerateCode(forNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
|
||||
GenerateCode(forNode.Increment,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
|
||||
|
||||
JumpUnconditional juC=new JumpUnconditional($"_label{labelNum}");
|
||||
chunk.Add(juC);
|
||||
LabelInstruction endLabel = new LabelInstruction($"_label{labelNumEnd}");
|
||||
|
@ -403,9 +419,11 @@ namespace TLang.BytecodeCompiler
|
|||
{
|
||||
BytecodeChunk _chunk = new BytecodeChunk();
|
||||
_chunk.Arguments = closureNode.Arguments;
|
||||
int i = Chunks.Count;
|
||||
|
||||
Chunks.Add(_chunk);
|
||||
GenerateCode(closureNode.Node,_chunk,0,0,-1,-1,false);
|
||||
int i = Chunks.Count;
|
||||
Chunks.Add(_chunk);
|
||||
|
||||
chunk.Add(new PushClosureNode(i));
|
||||
}
|
||||
if(node is NullNode)
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace TLang.Common
|
|||
public const byte GT = 0x17;
|
||||
public const byte GTE = 0x18;
|
||||
|
||||
public const byte POP = 0xE9;
|
||||
|
||||
public const byte SCOPE_BEGIN = 0xEA;
|
||||
public const byte SCOPE_END = 0xEB;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace TLang.Common
|
||||
{
|
||||
public class TLangDependency
|
||||
public class TLangDependency : IEquatable<TLangDependency>
|
||||
{
|
||||
public TLangDependency(string name,TLangVersion version)
|
||||
{
|
||||
|
@ -13,5 +15,10 @@ namespace TLang.Common
|
|||
}
|
||||
public string Name {get;set;}
|
||||
public TLangVersion Version {get;set;}
|
||||
|
||||
public bool Equals(TLangDependency other)
|
||||
{
|
||||
return Name == other.Name && Version.IntegerVersion == other.Version.IntegerVersion;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -64,10 +64,7 @@ namespace TLang.Lexer
|
|||
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 escapeI = 0;
|
||||
|
||||
|
@ -80,7 +77,7 @@ namespace TLang.Lexer
|
|||
{
|
||||
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));
|
||||
b2.Clear();
|
||||
e++;
|
||||
|
@ -104,12 +101,17 @@ namespace TLang.Lexer
|
|||
escapeI--;
|
||||
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.AddRange(Lex.GetTokensFromString(b2.ToString(),"compilerGenerated.tlang").Tokens);
|
||||
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();
|
||||
e++;
|
||||
}
|
||||
|
@ -128,18 +130,23 @@ namespace TLang.Lexer
|
|||
{
|
||||
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.AddRange(Lex.GetTokensFromString(b2.ToString(),"compilerGenerated.tlang").Tokens);
|
||||
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();
|
||||
e++;
|
||||
}
|
||||
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));
|
||||
b2.Clear();
|
||||
e++;
|
||||
|
@ -147,7 +154,7 @@ namespace TLang.Lexer
|
|||
}
|
||||
|
||||
|
||||
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace TLang.Lexer
|
|||
}
|
||||
if(consumeIfTrue) Offset += tokenText.Length;
|
||||
return new LexEntryContext(tokens,offset,true);
|
||||
|
||||
}
|
||||
|
||||
public LexEntryContext NextEntries(bool consumeIfTrue,params string[] tokenText)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TLang.Lexer;
|
||||
namespace TLang.Parser
|
||||
{
|
||||
|
@ -338,18 +339,63 @@ return res;
|
|||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Node ParseValue()
|
||||
{
|
||||
var doc = Context.PopDocumentation();
|
||||
var token = Context.NextEntry();
|
||||
if(token.IsString) return new StringNode(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 == "(")
|
||||
{
|
||||
var assignable = ParseAssigable();
|
||||
assignable.LineInfo = token.Position;
|
||||
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;
|
||||
}
|
||||
if(token.Text == "class")
|
||||
|
@ -606,6 +652,7 @@ return res;
|
|||
}
|
||||
else if(Context.MoreTokens && Context.NextEntries(false,"[").Success)
|
||||
{
|
||||
ret = new GetMemberNode(ret,token2.Text);
|
||||
while(Context.MoreTokens && Context.NextEntries(true,"[").Success)
|
||||
{
|
||||
var p = ParseNode();
|
||||
|
@ -616,9 +663,11 @@ return res;
|
|||
else
|
||||
{
|
||||
ret = new GetMemberNode(ret,token2.Text){LineInfo = token2.Position};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(Context.MoreTokens && Context.NextEntries(true,"++").Success)
|
||||
{
|
||||
var r = new PostFixIncrementNode(ret){LineInfo = ret.LineInfo};
|
||||
|
@ -682,7 +731,7 @@ return res;
|
|||
ret = new GetArrayNode(ret,p){LineInfo = p.LineInfo};
|
||||
Context.NextEntries(true,"]");
|
||||
}
|
||||
while(Context.MoreTokens && Context.NextEntries(true,".").Success)
|
||||
while(Context.MoreTokens && Context.NextEntries(true,".").Success)
|
||||
{
|
||||
var token2 = Context.NextEntry();
|
||||
|
||||
|
@ -696,8 +745,10 @@ return res;
|
|||
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)
|
||||
{
|
||||
var p = ParseNode();
|
||||
|
@ -708,6 +759,7 @@ return res;
|
|||
else
|
||||
{
|
||||
ret = new GetMemberNode(ret,token2.Text){LineInfo = token2.Position};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,13 +2,13 @@ namespace TLang.Parser
|
|||
{
|
||||
public class GetArrayNode : SymbolNode
|
||||
{
|
||||
public SymbolNode Symbol {get;set;}
|
||||
public Node Symbol {get;set;}
|
||||
public Node Expression {get;set;}
|
||||
|
||||
public GetArrayNode(SymbolNode sym, Node expr)
|
||||
public GetArrayNode(Node sym, Node expr)
|
||||
{
|
||||
Symbol = sym;
|
||||
this.Name = sym.Name;
|
||||
this.Name = "";
|
||||
Expression = expr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ namespace TLang.Parser
|
|||
{
|
||||
public class MethodCallNode : SymbolNode
|
||||
{
|
||||
public SymbolNode Symbol {get;set;}
|
||||
public Node Symbol {get;set;}
|
||||
public List<Node> Arguments {get;set;}=new List<Node>();
|
||||
|
||||
public MethodCallNode(SymbolNode symbol, string name)
|
||||
public MethodCallNode(Node symbol, string name)
|
||||
{
|
||||
Symbol = symbol;
|
||||
Name = name;
|
||||
|
|
|
@ -6,5 +6,6 @@ namespace TLang.Parser
|
|||
{
|
||||
public LexLineInfo LineInfo {get;set;}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
@ -13,37 +13,44 @@ namespace TLang.VM
|
|||
|
||||
public override TObject GetObject(string key)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
if(key == "this")
|
||||
{
|
||||
return classInstance;
|
||||
}
|
||||
return oGenv.GetObject(key);
|
||||
}
|
||||
|
||||
public override TLangEnvironment GetParentEnvironment()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return oGenv;
|
||||
}
|
||||
|
||||
public override RootEnvironment GetRootEnvironment()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return oGenv.GetRootEnvironment();
|
||||
}
|
||||
|
||||
public override TLangEnvironment GetSubEnvironment()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return new SubEnvironment(this);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
if(key == "this") return true;
|
||||
return oGenv.HasObjectRecurse(key);
|
||||
}
|
||||
|
||||
public override void SetObject(string key, TObject value)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
if(key == "this") return;
|
||||
oGenv.SetObject(key,value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;}
|
||||
}
|
||||
}
|
|
@ -2,14 +2,12 @@ namespace TLang.VM
|
|||
{
|
||||
public class ClassMethod
|
||||
{
|
||||
public bool Public {get;set;}
|
||||
public string ClassName {get;set;}
|
||||
|
||||
public bool Private {get;set;}
|
||||
|
||||
public bool Protected {get;set;}
|
||||
|
||||
public Chunk Chunk {get;set;}
|
||||
|
||||
public TVMFile File {get;set;}
|
||||
public TCallable Closure {get;set;}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using TLang.Common;
|
||||
|
||||
namespace TLang.VM
|
||||
|
@ -8,14 +9,14 @@ namespace TLang.VM
|
|||
public class DefaultDependencyPool : IDependencyPool
|
||||
{
|
||||
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";
|
||||
if(File.Exists(fileName))
|
||||
{
|
||||
using(var f = File.OpenRead(fileName))
|
||||
{
|
||||
TVMFile file = new TVMFile(f);
|
||||
TVMFile file = new TVMFile(f,env);
|
||||
items.Add((dependency,file));
|
||||
return file.LoadDependencies(this);
|
||||
}
|
||||
|
@ -34,17 +35,19 @@ namespace TLang.VM
|
|||
|
||||
public bool DependencyExists(TLangDependency dependency)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return items.Any(e=>
|
||||
e.Dependency.Equals(dependency)
|
||||
);
|
||||
}
|
||||
|
||||
public IEnumerator<(TLangDependency Dependency, TVMFile File)> GetEnumerator()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return this.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace TLang.VM
|
||||
{
|
||||
|
@ -7,7 +8,7 @@ namespace TLang.VM
|
|||
{
|
||||
public RootEnvironment()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
public Dictionary<string, LoadedClassData> AvailableClasses {get;set;}=new Dictionary<string, LoadedClassData>();
|
||||
|
||||
|
@ -48,5 +49,128 @@ namespace TLang.VM
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ namespace TLang.VM
|
|||
}
|
||||
public override bool HasObjectRecurse(string key)
|
||||
{
|
||||
return HasObject(key) && pEnv.HasObjectRecurse(key);
|
||||
return HasObject(key) || pEnv.HasObjectRecurse(key);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,9 @@ namespace TLang.VM
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ namespace TLang.VM
|
|||
{
|
||||
public class TClassInstance : TObject
|
||||
{
|
||||
public override string Type => $"class {classEntry.Name} : {classEntry.InheritsFrom}";
|
||||
public override bool True => true;
|
||||
TVMFile file;
|
||||
Class classEntry;
|
||||
TLangEnvironment oGenv;
|
||||
|
@ -17,6 +19,8 @@ namespace TLang.VM
|
|||
public List<string> InheritenceTree {get;}=new List<string>();
|
||||
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)
|
||||
|
@ -25,12 +29,34 @@ namespace TLang.VM
|
|||
|
||||
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 aC =oGenv.GetRootEnvironment().AvailableClasses;
|
||||
//we need to check inheritence
|
||||
while(cE.InheritsFrom != "object")
|
||||
while(cE.InheritsFrom != "object" && cE.InheritsFrom != "")
|
||||
{
|
||||
InheritenceTree.Add(cE.InheritsFrom);
|
||||
if(aC.ContainsKey(cE.InheritsFrom))
|
||||
|
@ -39,43 +65,104 @@ namespace TLang.VM
|
|||
cE = aC2.ToClass(cE.InheritsFrom);
|
||||
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(item.Abstract) throw new Exception("Method is abstract");
|
||||
ClassMethod meth=new ClassMethod();
|
||||
meth.File = aC2.File;
|
||||
meth.Chunk = aC2.File.Chunks[item.ChunkId];
|
||||
TClosure closure=new TClosure(aC2.File,aC2.File.Chunks[item.ChunkId],Environment);
|
||||
meth.ClassName = cE.Name;
|
||||
meth.Closure = closure;
|
||||
meth.Private = item.Private;
|
||||
meth.Protected = item.Protected;
|
||||
meth.Public = item.Public;
|
||||
|
||||
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 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)
|
||||
{
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if(Methods.ContainsKey(key))
|
||||
{
|
||||
var method=Methods[key];
|
||||
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();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return CallMethod(classEntry.Name,"toString").ToString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ namespace TLang.VM
|
|||
{
|
||||
public class TClosure : TCallable
|
||||
{
|
||||
|
||||
private TVMFile file;
|
||||
private Chunk chunk;
|
||||
private TLangEnvironment env;
|
||||
|
@ -16,6 +17,7 @@ namespace TLang.VM
|
|||
public override TObject Execute(params TObject[] args)
|
||||
{
|
||||
ChunkExecuter executer = new ChunkExecuter(file,chunk,env);
|
||||
executer.ClassName=ClassName;
|
||||
return executer.Execute(args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,5 +2,11 @@ namespace TLang.VM
|
|||
{
|
||||
public class TNull : TObject
|
||||
{
|
||||
public override string Type => "null";
|
||||
public override bool True => false;
|
||||
public override string ToString()
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,11 +2,17 @@ namespace TLang.VM
|
|||
{
|
||||
public class TNumber : TObject
|
||||
{
|
||||
public override string Type => "number";
|
||||
public override bool True => Value != 0;
|
||||
public double Value {get;set;}
|
||||
|
||||
public TNumber(double value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
namespace TLang.VM
|
||||
{
|
||||
public class TObject
|
||||
public abstract class TObject
|
||||
{
|
||||
public abstract string Type {get;}
|
||||
public abstract bool True { get; }
|
||||
}
|
||||
}
|
|
@ -1,12 +1,34 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace TLang.VM
|
||||
{
|
||||
public class TString : TObject
|
||||
{
|
||||
public override string Type => "string";
|
||||
public override bool True => !string.IsNullOrWhiteSpace(Value);
|
||||
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)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,5 +2,11 @@ namespace TLang.VM
|
|||
{
|
||||
public class TUndefined : TObject
|
||||
{
|
||||
public override string Type => "undefined";
|
||||
public override bool True => false;
|
||||
public override string ToString()
|
||||
{
|
||||
return "undefined";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,8 @@ namespace TLang.VM
|
|||
public List<Chunk> Chunks {get;set;}=new List<Chunk>();
|
||||
public TLangVersion Version {get;set;}
|
||||
public RootEnvironment Environment {get;private set;}
|
||||
|
||||
public ChunkExecuter DefaultChunkExecuter => new ChunkExecuter(this,Chunks[0],Environment);
|
||||
public TVMFile(Stream file,RootEnvironment env)
|
||||
{
|
||||
Environment = env;
|
||||
|
@ -141,6 +143,11 @@ namespace TLang.VM
|
|||
foreach(var class0 in Classes)
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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();
|
|
@ -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>
|
|
@ -0,0 +1 @@
|
|||
Demi Lovato
|
|
@ -0,0 +1,4 @@
|
|||
ensure Api;
|
||||
|
||||
|
||||
con.println(typeof(Api));
|
|
@ -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");
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
using TLang.VM;
|
||||
using var f = File.OpenRead("app.tvm");
|
||||
TVMFile file = new TVMFile(f);
|
||||
|
||||
ChunkExecuter executer=new ChunkExecuter(file,file.Chunks[0],new RootEnvironment());
|
||||
var env=new RootEnvironment();
|
||||
TVMFile file = new TVMFile(f,env);
|
||||
file.LoadDependencies(new DefaultDependencyPool());
|
||||
ChunkExecuter executer=new ChunkExecuter(file,file.Chunks[0],env);
|
||||
var res=executer.Execute() as TNumber;
|
||||
if(res != null)
|
||||
{
|
||||
Console.WriteLine($"Number: {res.Value}");
|
||||
}
|
||||
}
|
||||
|
|
BIN
VMTest/app.tvm
BIN
VMTest/app.tvm
Binary file not shown.
Loading…
Reference in New Issue