Initial commit

This commit is contained in:
Deukhoofd 2019-06-05 17:50:01 +02:00
commit cd185ed2e5
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
17 changed files with 482 additions and 0 deletions

33
.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
# Common IntelliJ Platform excludes
# User specific
**/.idea/**/workspace.xml
**/.idea/**/tasks.xml
**/.idea/shelf/*
**/.idea/dictionaries
# Sensitive or high-churn files
**/.idea/**/dataSources/
**/.idea/**/dataSources.ids
**/.idea/**/dataSources.xml
**/.idea/**/dataSources.local.xml
**/.idea/**/sqlDataSources.xml
**/.idea/**/dynamic.xml
# Rider
# Rider auto-generates .iml files, and contentModel.xml
**/.idea/**/*.iml
**/.idea/**/contentModel.xml
**/.idea/**/modules.xml
*.suo
*.user
.vs/
[Bb]in/
[Oo]bj/
_UpgradeReport_Files/
[Pp]ackages/
Thumbs.db
Desktop.ini
.DS_Store

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ContentModelUserStore">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

28
PorygonSharp.sln Normal file
View File

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PorygonSharp", "PorygonSharp\PorygonSharp.csproj", "{0C0E73BC-C4D9-498F-8A41-E247B104DF84}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PorygonSharpTests", "PorygonSharpTests\PorygonSharpTests.csproj", "{095D66BC-028A-49D0-8E4B-ED407D3AA20F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PorygonSharpCLI", "PorygonSharpCLI\PorygonSharpCLI.csproj", "{8F945B4C-8F2A-401C-8568-FD2BC94E5A39}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0C0E73BC-C4D9-498F-8A41-E247B104DF84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C0E73BC-C4D9-498F-8A41-E247B104DF84}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C0E73BC-C4D9-498F-8A41-E247B104DF84}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C0E73BC-C4D9-498F-8A41-E247B104DF84}.Release|Any CPU.Build.0 = Release|Any CPU
{095D66BC-028A-49D0-8E4B-ED407D3AA20F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{095D66BC-028A-49D0-8E4B-ED407D3AA20F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{095D66BC-028A-49D0-8E4B-ED407D3AA20F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{095D66BC-028A-49D0-8E4B-ED407D3AA20F}.Release|Any CPU.Build.0 = Release|Any CPU
{8F945B4C-8F2A-401C-8568-FD2BC94E5A39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8F945B4C-8F2A-401C-8568-FD2BC94E5A39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8F945B4C-8F2A-401C-8568-FD2BC94E5A39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8F945B4C-8F2A-401C-8568-FD2BC94E5A39}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Porygon/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -0,0 +1,21 @@
namespace PorygonSharp.DiagnosticHandling
{
public enum DiagnosticCode
{
// Lex diagnostics
UnexpectedCharacter,
InvalidStringControlCharacter,
// Parse diagnostics
UnexpectedToken,
// Bind diagnostics
NoBinaryOperationFound,
NoUnaryOperationFound,
CantAssignVariable,
VariableNotFound,
ExpressionIsNotAFunction,
ParameterCountMismatch,
ParameterTypeMismatch,
}
}

View File

@ -0,0 +1,18 @@
using System.Runtime.InteropServices;
namespace PorygonSharp.DiagnosticHandling
{
[StructLayout(LayoutKind.Sequential)]
public struct DiagnosticItem
{
private readonly int _severity;
private readonly DiagnosticCode _code;
private readonly uint _start;
private readonly uint _length;
public DiagnosticCode GetCode()
{
return _code;
}
}
}

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace PorygonSharp.DiagnosticHandling
{
[StructLayout(LayoutKind.Sequential)]
internal struct InternalDiagnostics
{
private readonly byte _hasErrors;
public bool HasErrors()
{
return _hasErrors == 1;
}
}
public class Diagnostics : IDisposable
{
private readonly IntPtr _handle;
private InternalDiagnostics _internal;
public Diagnostics(IntPtr handle)
{
_handle = handle;
_internal = Marshal.PtrToStructure<InternalDiagnostics>(handle);
}
public void Dispose()
{
Marshal.FreeHGlobal(_handle);
}
public bool HasErrors()
{
return _internal.HasErrors();
}
public int DiagnosticsCount()
{
return GetDiagnosticsCount(_handle);
}
public IEnumerable<DiagnosticItem> GetDiagnostics()
{
var count = DiagnosticsCount();
for (var i = 0; i < count; i++)
{
var ptr = GetDiagnosticAt(_handle, i);
yield return Marshal.PtrToStructure<DiagnosticItem>(ptr);
}
}
[DllImport("libPorygonLang", EntryPoint = "GetDiagnosticsCount")]
private static extern int GetDiagnosticsCount(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "GetDiagnosticAt")]
private static extern IntPtr GetDiagnosticAt(IntPtr ptr, int position);
}
}

64
PorygonSharp/EvalValue.cs Normal file
View File

@ -0,0 +1,64 @@
using System;
using System.Runtime.InteropServices;
namespace PorygonSharp
{
public class EvalValue : IDisposable
{
private IntPtr _handle;
public EvalValue(IntPtr handle)
{
_handle = handle;
}
public void Dispose()
{
if (_handle != IntPtr.Zero)
{
Marshal.FreeHGlobal(_handle);
_handle = IntPtr.Zero;
}
}
public TypeClass GetTypeClass()
{
return (TypeClass)GetTypeClass(_handle);
}
public long EvaluateInteger()
{
return EvaluateInteger(_handle);
}
public double EvaluateFloat()
{
return EvaluateFloat(_handle);
}
public bool EvaluateBool()
{
return EvaluateBool(_handle);
}
public string EvaluateString()
{
var ptr = EvaluateString(_handle);
return Marshal.PtrToStringUTF8(ptr);
}
[DllImport("libPorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetTypeClass(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "GetEvalValueType", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetScriptType(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateEvalValueInteger", CallingConvention = CallingConvention.Cdecl)]
private static extern long EvaluateInteger(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateEvalValueFloat", CallingConvention = CallingConvention.Cdecl)]
private static extern double EvaluateFloat(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateEvalValueBool", CallingConvention = CallingConvention.Cdecl)]
private static extern bool EvaluateBool(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateEvalValueString",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr EvaluateString(IntPtr ptr);
}
}

View File

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>

70
PorygonSharp/Script.cs Normal file
View File

@ -0,0 +1,70 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using PorygonSharp.DiagnosticHandling;
namespace PorygonSharp
{
[StructLayout(LayoutKind.Sequential)]
internal struct InternalScript
{
private readonly IntPtr _evaluator;
private readonly IntPtr _scriptVariables;
private readonly IntPtr _boundScript;
internal readonly IntPtr Diagnostics;
}
public class Script : IDisposable
{
private readonly IntPtr _internalScriptHandle;
private readonly InternalScript _internalScript;
private Diagnostics _diagnostics;
public Diagnostics Diagnostics => _diagnostics ?? (_diagnostics = new Diagnostics(_internalScript.Diagnostics));
public Script(string s)
{
_internalScriptHandle = Create(new StringBuilder(s));
_internalScript = Marshal.PtrToStructure<InternalScript>(_internalScriptHandle);
}
public void Dispose()
{
Marshal.FreeHGlobal(_internalScriptHandle);
Diagnostics.Dispose();
}
public void Evaluate()
{
Evaluate(_internalScriptHandle);
}
public EvalValue GetLastValue()
{
var ptr = GetLastValue(_internalScriptHandle);
return new EvalValue(ptr);
}
public bool HasVariable(string key)
{
return HasVariable(_internalScriptHandle, key);
}
public EvalValue GetVariable(string key)
{
var ptr = GetVariable(_internalScriptHandle, key);
return new EvalValue(ptr);
}
[DllImport("libPorygonLang", EntryPoint = "CreateScript", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr Create(StringBuilder s);
[DllImport("libPorygonLang", EntryPoint = "EvaluateScript", CallingConvention = CallingConvention.Cdecl)]
private static extern void Evaluate(IntPtr script);
[DllImport("libPorygonLang", EntryPoint = "GetLastValue", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetLastValue(IntPtr script);
[DllImport("libPorygonLang", EntryPoint = "HasVariable", CallingConvention = CallingConvention.Cdecl)]
private static extern bool HasVariable(IntPtr script, string key);
[DllImport("libPorygonLang", EntryPoint = "GetVariable", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetVariable(IntPtr script, string key);
}
}

14
PorygonSharp/TypeClass.cs Normal file
View File

@ -0,0 +1,14 @@
namespace PorygonSharp
{
public enum TypeClass
{
Error,
Nil,
Number,
Bool,
String,
Function,
UserData,
Table,
}
}

View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PorygonSharp\PorygonSharp.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,22 @@
using System;
using System.Diagnostics;
using PorygonSharp;
namespace PorygonSharpCLI
{
class Program
{
static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
for (var i = 0; i < 100000; i++)
{
var script = new Script("a = 500");
script.Evaluate();
script.Dispose();
}
sw.Stop();
Console.WriteLine($"Time elapsed: {sw.ElapsedMilliseconds}");
}
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PorygonSharp\PorygonSharp.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,97 @@
using System;
using NUnit.Framework;
using PorygonSharp;
namespace PorygonSharpTests
{
public class Tests
{
[Test]
public void Test1()
{
using (var script = new Script("true"))
{
var diags = script.Diagnostics.GetDiagnostics();
foreach (var diag in diags)
{
throw new Exception(diag.GetCode().ToString());
}
Assert.False(script.Diagnostics.HasErrors());
}
}
[Test]
public void Test2()
{
using (var script = new Script("1+true"))
{
Assert.True(script.Diagnostics.HasErrors());
}
}
[Test]
public void Test3()
{
using (var script = new Script("1+10"))
{
script.Evaluate();
var lastVal = script.GetLastValue();
Assert.AreEqual(TypeClass.Number, lastVal.GetTypeClass());
var val = lastVal.EvaluateInteger();
Assert.AreEqual(11, val);
}
}
[Test]
public void Test4()
{
using (var script = new Script("1+10.24"))
{
script.Evaluate();
var lastVal = script.GetLastValue();
Assert.AreEqual(TypeClass.Number, lastVal.GetTypeClass());
var val = lastVal.EvaluateFloat();
Assert.AreEqual(11.24d, val, 5);
}
}
[Test]
public void Test5()
{
using (var script = new Script("true and true"))
{
script.Evaluate();
var lastVal = script.GetLastValue();
Assert.AreEqual(TypeClass.Bool, lastVal.GetTypeClass());
var val = lastVal.EvaluateBool();
Assert.AreEqual(true, val);
}
}
[Test]
public void Test6()
{
using (var script = new Script("'foo' + 'bar'"))
{
script.Evaluate();
var lastVal = script.GetLastValue();
Assert.AreEqual(TypeClass.String, lastVal.GetTypeClass());
var val = lastVal.EvaluateString();
Assert.AreEqual("foobar", val);
}
}
[Test]
public void Test7()
{
using (var script = new Script("a = 100 + 50"))
{
script.Evaluate();
var variable = script.GetVariable("a");
Assert.AreEqual(TypeClass.Number, variable.GetTypeClass());
var val = variable.EvaluateInteger();
Assert.AreEqual(150, val);
}
}
}
}

BIN
libPorygonLang.so Executable file

Binary file not shown.