forked from vr-voyage/SharpLogix
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Major refactoring and basic variable creation
- Loading branch information
1 parent
ed1894a
commit 1afe4b3
Showing
12 changed files
with
739 additions
and
318 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Symbols; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Microsoft.CodeAnalysis.MSBuild; | ||
using Microsoft.CodeAnalysis.Text; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Numerics; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
using BaseX; | ||
using FrooxEngine; | ||
using FrooxEngine.LogiX; | ||
using System.Reflection; | ||
|
||
namespace SharpLogix.Core | ||
{ | ||
/// <summary> | ||
/// A hellscape of generics. | ||
/// </summary> | ||
class ExperimentalSyntaxWalker : CSharpSyntaxWalker | ||
{ | ||
public static readonly List<Type> LogixNodeTypes = new List<Type>(); | ||
|
||
int RecursionLevel; | ||
int CurrentNamespace = -1; | ||
int CurrentScript = -1; | ||
readonly Slot SpawnRoot; | ||
readonly List<SharpLogixScript> sharpLogixScripts = new List<SharpLogixScript>(); | ||
|
||
readonly SemanticModel semanticModel; | ||
|
||
static ExperimentalSyntaxWalker() | ||
{ | ||
foreach (Type AvailableType in AppDomain.CurrentDomain.GetAssemblies(). | ||
SelectMany(assemblies => assemblies.GetTypes()). | ||
Where(currentType => currentType.IsSubclassOf(typeof(LogixNode)))) | ||
{ | ||
LogixNodeTypes.Add(AvailableType); | ||
} | ||
} | ||
|
||
public ExperimentalSyntaxWalker(Slot spawnRoot, string Name, SemanticModel model) | ||
{ | ||
semanticModel = model; | ||
SpawnRoot = spawnRoot.AddSlot(Name); | ||
} | ||
|
||
public override void Visit(SyntaxNode node) | ||
{ | ||
//string indents = new string('\t', Tabs); | ||
//Core.Debug.Log(indents + node.Kind()); | ||
RecursionLevel++; | ||
base.Visit(node); | ||
RecursionLevel--; | ||
} | ||
|
||
//Assume one namespace for now. | ||
/* | ||
public override void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) | ||
{ | ||
CurrentNamespace++; | ||
node.Name.ToString(); | ||
base.VisitNamespaceDeclaration(node); | ||
} | ||
*/ | ||
|
||
public override void VisitClassDeclaration(ClassDeclarationSyntax node) | ||
{ | ||
//Class information. Eg myClass. | ||
sharpLogixScripts.Add(new SharpLogixScript(SpawnRoot)); | ||
CurrentScript++; | ||
|
||
string identifier = node.Identifier.ValueText; | ||
|
||
sharpLogixScripts[CurrentScript].Root.Name = identifier; | ||
sharpLogixScripts[CurrentScript].Root.AttachComponent<DynamicVariableSpace>().SpaceName.Value = identifier; | ||
|
||
base.VisitClassDeclaration(node); | ||
} | ||
|
||
public override void VisitFieldDeclaration(FieldDeclarationSyntax node) | ||
{ | ||
base.VisitFieldDeclaration(node); | ||
} | ||
public override void VisitVariableDeclaration(VariableDeclarationSyntax node) | ||
{ | ||
foreach (VariableDeclaratorSyntax variable in node.Variables) | ||
{ | ||
Slot VariableSlot = sharpLogixScripts[CurrentScript].Members.AddSlot(string.Concat(node.Type.ToString(), " ", variable.Identifier.ValueText)); | ||
Type VariableType = Type.GetType(GetFullMetadataName(semanticModel.GetSymbolInfo(node.Type).Symbol)); | ||
|
||
object Initializer = null; | ||
|
||
if (variable.Initializer != null) | ||
{ | ||
Initializer = Convert.ChangeType(variable.Initializer.ChildNodes().First().ToString(), VariableType); | ||
} | ||
|
||
Type[] dynVarType = new Type[1] { VariableType }; | ||
if (VariableType.IsClass && typeof(IWorldElement).IsAssignableFrom(VariableType)) | ||
{ | ||
MethodInfo method = GetType().GetMethod(nameof(AddDRV), BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(Slot), typeof(string), typeof(object) }, null); | ||
MethodInfo generic = method.MakeGenericMethod(dynVarType); | ||
object[] parameters = new object[3] { VariableSlot, variable.Identifier.ValueText, Initializer }; | ||
generic.Invoke(this, parameters); | ||
} | ||
else | ||
{ | ||
MethodInfo method = GetType().GetMethod(nameof(AddDVV), BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(Slot), typeof(string), typeof(object) }, null); | ||
MethodInfo generic = method.MakeGenericMethod(dynVarType); | ||
object[] parameters = new object[3] { VariableSlot, variable.Identifier.ValueText, Initializer }; | ||
generic.Invoke(this, parameters); | ||
} | ||
} | ||
|
||
base.VisitVariableDeclaration(node); | ||
} | ||
void AddDRV<T>(Slot slot, string name, object value) where T : class, IWorldElement | ||
{ | ||
var drv = slot.AttachComponent<DynamicReferenceVariable<T>>(); | ||
drv.VariableName.Value = name; | ||
|
||
if (value != null) | ||
{ | ||
drv.DynamicValue = (T)value; | ||
} | ||
} | ||
void AddDVV<T>(Slot slot, string name, object value) | ||
{ | ||
var drv = slot.AttachComponent<DynamicValueVariable<T>>(); | ||
drv.VariableName.Value = name; | ||
|
||
if (value != null) | ||
{ | ||
drv.DynamicValue = (T)value; | ||
} | ||
} | ||
|
||
//Magic | ||
static string GetFullMetadataName(ISymbol s) | ||
{ | ||
if (s == null || IsRootNamespace(s)) | ||
{ | ||
return string.Empty; | ||
} | ||
|
||
var sb = new StringBuilder(s.MetadataName); | ||
var last = s; | ||
|
||
s = s.ContainingSymbol; | ||
|
||
while (!IsRootNamespace(s)) | ||
{ | ||
if (s is ITypeSymbol && last is ITypeSymbol) | ||
{ | ||
sb.Insert(0, '+'); | ||
} | ||
else | ||
{ | ||
sb.Insert(0, '.'); | ||
} | ||
|
||
sb.Insert(0, s.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); | ||
//sb.Insert(0, s.MetadataName); | ||
s = s.ContainingSymbol; | ||
} | ||
|
||
return sb.ToString(); | ||
} | ||
static bool IsRootNamespace(ISymbol symbol) | ||
{ | ||
INamespaceSymbol s = null; | ||
return ((s = symbol as INamespaceSymbol) != null) && s.IsGlobalNamespace; | ||
} | ||
|
||
public override void VisitMethodDeclaration(MethodDeclarationSyntax node) | ||
{ | ||
sharpLogixScripts[CurrentScript].Methods.AddSlot(string.Concat(node.ReturnType.ToString(), " ", node.Identifier.ValueText, "()")); | ||
|
||
base.VisitMethodDeclaration(node); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace SharpLogix.Core | ||
{ | ||
/// <summary> | ||
/// The class responsible for constructing the actual node graphs. | ||
/// </summary> | ||
class LogixBuilder | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
using NeosModLoader; | ||
using HarmonyLib; | ||
using BaseX; | ||
using FrooxEngine; | ||
|
||
namespace SharpLogix.Core | ||
{ | ||
class SharpLogixCompiler : NeosMod | ||
{ | ||
public override string Name => "SharpLogix"; | ||
//Originally forked from: https://github.com/vr-voyage/SharpLogix and refactored into a nml mod. | ||
public override string Author => "Toxic_Cookie"; | ||
public override string Version => "1.0.0"; | ||
public override string Link => "https://github.com/Toxic-Cookie/SharpLogix"; | ||
public override void OnEngineInit() | ||
{ | ||
Core.Debug.Log("Hello World!"); | ||
|
||
Harmony harmony = new Harmony("net.Toxic_Cookie.SharpLogix"); | ||
harmony.PatchAll(); | ||
} | ||
|
||
[HarmonyPatch(typeof(ImageImportDialog), "OnAttach")] | ||
class ImportScript | ||
{ | ||
public static void Postfix() | ||
{ | ||
string MyProgram = @" | ||
namespace MyProgram | ||
{ | ||
class Class1 | ||
{ | ||
int TestIntA; | ||
int TestIntB = 3; | ||
int TestIntC; | ||
void Start() | ||
{ | ||
TestIntA = 2; | ||
TestIntC = TestIntA + TestIntB; | ||
} | ||
} | ||
} | ||
"; | ||
|
||
new SharpLogixProgram(MyProgram, "Hello World"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using BaseX; | ||
using FrooxEngine; | ||
|
||
namespace SharpLogix.Core | ||
{ | ||
class SharpLogixProgram | ||
{ | ||
public SharpLogixProgram(string Program, string Name = "Unnamed Program", Slot spawnRoot = null) | ||
{ | ||
if (spawnRoot == null) | ||
{ | ||
spawnRoot = Engine.Current.WorldManager.FocusedWorld.RootSlot; | ||
} | ||
//slx = SharpLogix | ||
if (!Name.EndsWith(".slx")) | ||
{ | ||
Name = string.Concat(Name, ".slx"); | ||
} | ||
|
||
SyntaxTree tree = CSharpSyntaxTree.ParseText(Program); | ||
|
||
//Might require end user to reference their libs. A given but oof. | ||
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); | ||
var compilation = CSharpCompilation.Create("slxCompilation", syntaxTrees: new[] { tree }, references: new[] { mscorlib }); | ||
|
||
ExperimentalSyntaxWalker walker = new ExperimentalSyntaxWalker(spawnRoot, Name, compilation.GetSemanticModel(tree)); | ||
walker.Visit(tree.GetRoot()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
using BaseX; | ||
using FrooxEngine; | ||
using FrooxEngine.LogiX; | ||
|
||
namespace SharpLogix.Core | ||
{ | ||
/// <summary> | ||
/// A Neos representation of a class. | ||
/// </summary> | ||
class SharpLogixScript | ||
{ | ||
public readonly Slot SpawnSlot; | ||
public readonly Slot Root; | ||
public readonly Slot Assembly; | ||
public readonly Slot Members; | ||
public readonly Slot Methods; | ||
public readonly Slot Debug; | ||
|
||
public SharpLogixScript(Slot spawnRoot, string Name = "Unnamed Script") | ||
{ | ||
SpawnSlot = spawnRoot; | ||
Root = SpawnSlot.AddSlot(Name); | ||
Assembly = Root.AddSlot("Assembly"); | ||
Members = Assembly.AddSlot("Members"); | ||
Methods = Assembly.AddSlot("Methods"); | ||
Debug = Assembly.AddSlot("Debug"); | ||
} | ||
} | ||
} |
File renamed without changes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
| ||
################ | ||
PARSING RULES: | ||
################ | ||
|
||
Variables | ||
========= | ||
Local Variables: Represented as Value / Reference Registers. | ||
Global Variables: Represented as Dynamic Variables. | ||
Literals: Represented as input nodes. | ||
|
||
Methods | ||
======= | ||
Methods will be called via impulses. | ||
|
||
Program Flow | ||
============ | ||
if, for, while, etc will be interpreted literally. | ||
?:, ??, etc will be drive based. | ||
|
||
Component Access | ||
================ | ||
Only members setup to be accessible at compile time will be accessible. |
Oops, something went wrong.