Neue Architektur
This commit is contained in:
42
.vscode/launch.json
vendored
Normal file
42
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Launch STCompiler.Compiler",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler",
|
||||
"args": ["${workspaceFolder}/STCompiler.Compiler/input.st", "${workspaceFolder}/STCompiler.Compiler/output.bin"],
|
||||
"cwd": "${workspaceFolder}/STCompiler.Compiler",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Launch STCompiler.Disassembler",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Disassembler",
|
||||
"args": ["${workspaceFolder}/STCompiler.Compiler/output.bin"],
|
||||
"cwd": "${workspaceFolder}/STCompiler.Disassembler",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Launch STCompiler.Simulator",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Simulator",
|
||||
"args": ["${workspaceFolder}/STCompiler.Compiler/output.bin"],
|
||||
"cwd": "${workspaceFolder}/STCompiler.Simulator",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Attach to .NET",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}"
|
||||
}
|
||||
]
|
||||
}
|
||||
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"csharp.suppressDotnetRestoreNotification": true,
|
||||
"dotnet.defaultSolution": "${workspaceFolder}/STCompiler.sln"
|
||||
}
|
||||
37
.vscode/tasks.json
vendored
Normal file
37
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": ["build", "${workspaceFolder}/STCompiler.sln"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": ["$msCompile"]
|
||||
},
|
||||
{
|
||||
"label": "run:compiler",
|
||||
"type": "process",
|
||||
"command": "dotnet",
|
||||
"args": ["run", "--project", "${workspaceFolder}/STCompiler.Compiler/STCompiler.Compiler.csproj", "--", "${workspaceFolder}/STCompiler.Compiler/input.st", "${workspaceFolder}/STCompiler.Compiler/output.bin"],
|
||||
"presentation": { "reveal": "always", "panel": "shared" }
|
||||
},
|
||||
{
|
||||
"label": "run:disassembler",
|
||||
"type": "process",
|
||||
"command": "dotnet",
|
||||
"args": ["run", "--project", "${workspaceFolder}/STCompiler.Disassembler/STCompiler.Disassembler.csproj", "--", "${workspaceFolder}/STCompiler.Compiler/output.bin"],
|
||||
"presentation": { "reveal": "always", "panel": "shared" }
|
||||
},
|
||||
{
|
||||
"label": "run:simulator",
|
||||
"type": "process",
|
||||
"command": "dotnet",
|
||||
"args": ["run", "--project", "${workspaceFolder}/STCompiler.Simulator/STCompiler.Simulator.csproj", "--", "${workspaceFolder}/STCompiler.Compiler/output.bin"],
|
||||
"presentation": { "reveal": "always", "panel": "shared" }
|
||||
}
|
||||
]
|
||||
}
|
||||
70
STCompiler.Common/Bytecode.cs
Normal file
70
STCompiler.Common/Bytecode.cs
Normal file
@ -0,0 +1,70 @@
|
||||
namespace STCompiler.Common;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class Bytecode {
|
||||
public const string Magic = "STBC";
|
||||
public const ushort Version = 2;
|
||||
|
||||
public static class OpCodes {
|
||||
public const byte NOP = 0x00;
|
||||
public const byte PUSH_CONST = 0x01; // integer/long
|
||||
public const byte PUSH_REAL_CONST = 0x02; // float/double
|
||||
public const byte LOAD_VAR = 0x03;
|
||||
public const byte STORE_VAR = 0x04;
|
||||
|
||||
// Signed integer arithmetic (SINT, INT, DINT, LINT)
|
||||
public const byte ADD_SINT = 0x10; public const byte SUB_SINT = 0x11; public const byte MUL_SINT = 0x12; public const byte DIV_SINT = 0x13;
|
||||
public const byte ADD_INT = 0x14; public const byte SUB_INT = 0x15; public const byte MUL_INT = 0x16; public const byte DIV_INT = 0x17;
|
||||
public const byte ADD_DINT = 0x18; public const byte SUB_DINT = 0x19; public const byte MUL_DINT = 0x1A; public const byte DIV_DINT = 0x1B;
|
||||
public const byte ADD_LINT = 0x1C; public const byte SUB_LINT = 0x1D; public const byte MUL_LINT = 0x1E; public const byte DIV_LINT = 0x1F;
|
||||
|
||||
// Unsigned integer arithmetic (USINT, UINT, UDINT, ULINT) - moved to avoid conflicts
|
||||
public const byte ADD_USINT = 0x22; public const byte SUB_USINT = 0x23; public const byte MUL_USINT = 0x24; public const byte DIV_USINT = 0x25;
|
||||
public const byte ADD_UINT = 0x26; public const byte SUB_UINT = 0x27; public const byte MUL_UINT = 0x28; public const byte DIV_UINT = 0x29;
|
||||
public const byte ADD_UDINT = 0x2A; public const byte SUB_UDINT = 0x2B; public const byte MUL_UDINT = 0x2C; public const byte DIV_UDINT = 0x2D;
|
||||
public const byte ADD_ULINT = 0x2E; public const byte SUB_ULINT = 0x2F; public const byte MUL_ULINT = 0x30; public const byte DIV_ULINT = 0x31;
|
||||
|
||||
// Floating point arithmetic
|
||||
public const byte ADD_REAL = 0x40; public const byte SUB_REAL = 0x41; public const byte MUL_REAL = 0x42; public const byte DIV_REAL = 0x43;
|
||||
public const byte ADD_LREAL = 0x44; public const byte SUB_LREAL = 0x45; public const byte MUL_LREAL = 0x46; public const byte DIV_LREAL = 0x47;
|
||||
|
||||
// Comparisons signed
|
||||
public const byte LT_S = 0x50; public const byte GT_S = 0x51; public const byte LE_S = 0x52; public const byte GE_S = 0x53; public const byte EQ_S = 0x54; public const byte NEQ_S = 0x55;
|
||||
// Comparisons unsigned
|
||||
public const byte LT_U = 0x56; public const byte GT_U = 0x57; public const byte LE_U = 0x58; public const byte GE_U = 0x59; public const byte EQ_U = 0x5A; public const byte NEQ_U = 0x5B;
|
||||
// Comparisons floating
|
||||
public const byte LT_F = 0x5C; public const byte GT_F = 0x5D; public const byte LE_F = 0x5E; public const byte GE_F = 0x5F; public const byte EQ_F = 0x60; public const byte NEQ_F = 0x61;
|
||||
|
||||
// Control flow
|
||||
public const byte JZ = 0x70;
|
||||
public const byte JMP = 0x71;
|
||||
|
||||
public const byte HALT = 0xF0;
|
||||
}
|
||||
|
||||
static readonly Dictionary<byte, string> names = new() {
|
||||
{ OpCodes.NOP, "NOP" },
|
||||
{ OpCodes.PUSH_CONST, "PUSH_CONST" },
|
||||
{ OpCodes.PUSH_REAL_CONST, "PUSH_REAL_CONST" },
|
||||
{ OpCodes.LOAD_VAR, "LOAD_VAR" },
|
||||
{ OpCodes.STORE_VAR, "STORE_VAR" },
|
||||
{ OpCodes.ADD_SINT, "ADD_SINT" }, { OpCodes.SUB_SINT, "SUB_SINT" }, { OpCodes.MUL_SINT, "MUL_SINT" }, { OpCodes.DIV_SINT, "DIV_SINT" },
|
||||
{ OpCodes.ADD_INT, "ADD_INT" }, { OpCodes.SUB_INT, "SUB_INT" }, { OpCodes.MUL_INT, "MUL_INT" }, { OpCodes.DIV_INT, "DIV_INT" },
|
||||
{ OpCodes.ADD_DINT, "ADD_DINT" }, { OpCodes.SUB_DINT, "SUB_DINT" }, { OpCodes.MUL_DINT, "MUL_DINT" }, { OpCodes.DIV_DINT, "DIV_DINT" },
|
||||
{ OpCodes.ADD_LINT, "ADD_LINT" }, { OpCodes.SUB_LINT, "SUB_LINT" }, { OpCodes.MUL_LINT, "MUL_LINT" }, { OpCodes.DIV_LINT, "DIV_LINT" },
|
||||
{ OpCodes.ADD_USINT, "ADD_USINT" }, { OpCodes.SUB_USINT, "SUB_USINT" }, { OpCodes.MUL_USINT, "MUL_USINT" }, { OpCodes.DIV_USINT, "DIV_USINT" },
|
||||
{ OpCodes.ADD_UINT, "ADD_UINT" }, { OpCodes.SUB_UINT, "SUB_UINT" }, { OpCodes.MUL_UINT, "MUL_UINT" }, { OpCodes.DIV_UINT, "DIV_UINT" },
|
||||
{ OpCodes.ADD_UDINT, "ADD_UDINT" }, { OpCodes.SUB_UDINT, "SUB_UDINT" }, { OpCodes.MUL_UDINT, "MUL_UDINT" }, { OpCodes.DIV_UDINT, "DIV_UDINT" },
|
||||
{ OpCodes.ADD_ULINT, "ADD_ULINT" }, { OpCodes.SUB_ULINT, "SUB_ULINT" }, { OpCodes.MUL_ULINT, "MUL_ULINT" }, { OpCodes.DIV_ULINT, "DIV_ULINT" },
|
||||
{ OpCodes.ADD_REAL, "ADD_REAL" }, { OpCodes.SUB_REAL, "SUB_REAL" }, { OpCodes.MUL_REAL, "MUL_REAL" }, { OpCodes.DIV_REAL, "DIV_REAL" },
|
||||
{ OpCodes.ADD_LREAL, "ADD_LREAL" }, { OpCodes.SUB_LREAL, "SUB_LREAL" }, { OpCodes.MUL_LREAL, "MUL_LREAL" }, { OpCodes.DIV_LREAL, "DIV_LREAL" },
|
||||
{ OpCodes.LT_S, "LT_S" }, { OpCodes.GT_S, "GT_S" }, { OpCodes.LE_S, "LE_S" }, { OpCodes.GE_S, "GE_S" }, { OpCodes.EQ_S, "EQ_S" }, { OpCodes.NEQ_S, "NEQ_S" },
|
||||
{ OpCodes.LT_U, "LT_U" }, { OpCodes.GT_U, "GT_U" }, { OpCodes.LE_U, "LE_U" }, { OpCodes.GE_U, "GE_U" }, { OpCodes.EQ_U, "EQ_U" }, { OpCodes.NEQ_U, "NEQ_U" },
|
||||
{ OpCodes.LT_F, "LT_F" }, { OpCodes.GT_F, "GT_F" }, { OpCodes.LE_F, "LE_F" }, { OpCodes.GE_F, "GE_F" }, { OpCodes.EQ_F, "EQ_F" }, { OpCodes.NEQ_F, "NEQ_F" },
|
||||
{ OpCodes.JZ, "JZ" }, { OpCodes.JMP, "JMP" },
|
||||
{ OpCodes.HALT, "HALT" }
|
||||
};
|
||||
|
||||
public static string OpName(byte op) => names.TryGetValue(op, out var s) ? s : ($"0x{op:X2}");
|
||||
}
|
||||
6
STCompiler.Common/Class1.cs
Normal file
6
STCompiler.Common/Class1.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace STCompiler.Common;
|
||||
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
9
STCompiler.Common/STCompiler.Common.csproj
Normal file
9
STCompiler.Common/STCompiler.Common.csproj
Normal file
@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
15
STCompiler.Common/VarType.cs
Normal file
15
STCompiler.Common/VarType.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace STCompiler.Common;
|
||||
|
||||
// Gemeinsame Variable types für Compiler, Disassembler und Simulator
|
||||
public enum VarType {
|
||||
// Boolean
|
||||
BOOL = 1,
|
||||
// Unsigned integers
|
||||
BYTE = 2, WORD = 3, DWORD = 4, LWORD = 5,
|
||||
// Signed integers
|
||||
SINT = 6, INT = 7, DINT = 8, LINT = 9,
|
||||
// Unsigned integers (alternative names)
|
||||
USINT = 10, UINT = 11, UDINT = 12, ULINT = 13,
|
||||
// Floating point
|
||||
REAL = 14, LREAL = 15
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v8.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"runtime": {
|
||||
"STCompiler.Common.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
STCompiler.Common/bin/Debug/net8.0/STCompiler.Common.dll
Normal file
BIN
STCompiler.Common/bin/Debug/net8.0/STCompiler.Common.dll
Normal file
Binary file not shown.
BIN
STCompiler.Common/bin/Debug/net8.0/STCompiler.Common.pdb
Normal file
BIN
STCompiler.Common/bin/Debug/net8.0/STCompiler.Common.pdb
Normal file
Binary file not shown.
@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("STCompiler.Common")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("STCompiler.Common")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("STCompiler.Common")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@ -0,0 +1 @@
|
||||
47f7f9783b0890c01839d6f882aac21cc3b1825ebf07d1532f3ffeb6d47e1764
|
||||
@ -0,0 +1,13 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net8.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = STCompiler.Common
|
||||
build_property.ProjectDir = /home/martin/Projects/STCompiler/STCompiler.Common/
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
@ -0,0 +1,8 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
Binary file not shown.
@ -0,0 +1 @@
|
||||
1c21a086cd38f15730e5b6283c22981505869f5cda3497f26cde2d0f5d493189
|
||||
@ -0,0 +1,11 @@
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/bin/Debug/net8.0/STCompiler.Common.deps.json
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/bin/Debug/net8.0/STCompiler.Common.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/bin/Debug/net8.0/STCompiler.Common.pdb
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.GeneratedMSBuildEditorConfig.editorconfig
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.AssemblyInfoInputs.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.AssemblyInfo.cs
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.csproj.CoreCompileInputs.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/obj/Debug/net8.0/refint/STCompiler.Common.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.pdb
|
||||
/home/martin/Projects/STCompiler/STCompiler.Common/obj/Debug/net8.0/ref/STCompiler.Common.dll
|
||||
BIN
STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.dll
Normal file
BIN
STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.dll
Normal file
Binary file not shown.
BIN
STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.pdb
Normal file
BIN
STCompiler.Common/obj/Debug/net8.0/STCompiler.Common.pdb
Normal file
Binary file not shown.
BIN
STCompiler.Common/obj/Debug/net8.0/ref/STCompiler.Common.dll
Normal file
BIN
STCompiler.Common/obj/Debug/net8.0/ref/STCompiler.Common.dll
Normal file
Binary file not shown.
BIN
STCompiler.Common/obj/Debug/net8.0/refint/STCompiler.Common.dll
Normal file
BIN
STCompiler.Common/obj/Debug/net8.0/refint/STCompiler.Common.dll
Normal file
Binary file not shown.
@ -0,0 +1,67 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"projectName": "STCompiler.Common",
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"packagesPath": "/home/martin/.nuget/packages/",
|
||||
"outputPath": "/home/martin/Projects/STCompiler/STCompiler.Common/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/martin/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.20, 8.0.20]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/8.0.120/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
STCompiler.Common/obj/STCompiler.Common.csproj.nuget.g.props
Normal file
15
STCompiler.Common/obj/STCompiler.Common.csproj.nuget.g.props
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/martin/.nuget/packages/</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/martin/.nuget/packages/</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.8.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="/home/martin/.nuget/packages/" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
72
STCompiler.Common/obj/project.assets.json
Normal file
72
STCompiler.Common/obj/project.assets.json
Normal file
@ -0,0 +1,72 @@
|
||||
{
|
||||
"version": 3,
|
||||
"targets": {
|
||||
"net8.0": {}
|
||||
},
|
||||
"libraries": {},
|
||||
"projectFileDependencyGroups": {
|
||||
"net8.0": []
|
||||
},
|
||||
"packageFolders": {
|
||||
"/home/martin/.nuget/packages/": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"projectName": "STCompiler.Common",
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"packagesPath": "/home/martin/.nuget/packages/",
|
||||
"outputPath": "/home/martin/Projects/STCompiler/STCompiler.Common/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/martin/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.20, 8.0.20]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/8.0.120/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
STCompiler.Common/obj/project.nuget.cache
Normal file
10
STCompiler.Common/obj/project.nuget.cache
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "jt2HMehc3BneQxy6gmHmXdh6VZS/3dtjkNjH2GR4yNPSBFcEqtHnBMxfL4LgGBL/hoFiIYvAdg6xhIGGboFt/w==",
|
||||
"success": true,
|
||||
"projectFilePath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"/home/martin/.nuget/packages/microsoft.aspnetcore.app.ref/8.0.20/microsoft.aspnetcore.app.ref.8.0.20.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
877
STCompiler.Compiler/Program.cs
Normal file
877
STCompiler.Compiler/Program.cs
Normal file
@ -0,0 +1,877 @@
|
||||
namespace STCompiler.Compiler;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using STCompiler.Common;
|
||||
|
||||
// === ENTRY POINT ===
|
||||
class Program {
|
||||
static int Main(string[] args) {
|
||||
if (args.Length < 2) {
|
||||
Console.WriteLine("Usage: StEmitter <input.st> <output.bin>");
|
||||
return 1;
|
||||
}
|
||||
|
||||
var input = File.ReadAllText(args[0]);
|
||||
var parser = new StParser(input);
|
||||
var prog = parser.ParseProgram();
|
||||
|
||||
if (parser.HasErrors) {
|
||||
Console.WriteLine($"Compilation failed with {parser.Errors.Count} errors:");
|
||||
foreach (var error in parser.Errors) {
|
||||
Console.WriteLine($"Error at line {error.Line}: {error.Message}");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (prog == null) {
|
||||
Console.WriteLine("Compilation failed: invalid program structure");
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
var emitter = new BytecodeEmitter();
|
||||
emitter.Compile(prog);
|
||||
File.WriteAllBytes(args[1], emitter.BuildBinary());
|
||||
Console.WriteLine($"Wrote {args[1]}: consts={emitter.ConstantsCount}, vars={emitter.VarCount}, code={emitter.CodeLength}");
|
||||
return 0;
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine($"Internal compiler error: {ex.Message}");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === AST ===
|
||||
public enum VarType {
|
||||
// Boolean
|
||||
BOOL=1,
|
||||
// Unsigned integers
|
||||
BYTE=2, WORD=3, DWORD=4, LWORD=5,
|
||||
// Signed integers
|
||||
SINT=6, INT=7, DINT=8, LINT=9,
|
||||
// Unsigned integers (alternative names)
|
||||
USINT=10, UINT=11, UDINT=12, ULINT=13,
|
||||
// Floating point
|
||||
REAL=14, LREAL=15
|
||||
}
|
||||
public abstract class StNode{}
|
||||
public class ProgramNode:StNode{ public List<VarDecl> Vars=new(); public List<Stmt> Stmts=new(); }
|
||||
public class VarDecl:StNode{
|
||||
required public string Name;
|
||||
public VarType Type;
|
||||
public Expr? Init;
|
||||
}
|
||||
|
||||
public abstract class Stmt:StNode{}
|
||||
public class AssignStmt:Stmt{
|
||||
required public string Target;
|
||||
required public Expr Expr;
|
||||
}
|
||||
public class IfStmt:Stmt{
|
||||
required public Expr Cond;
|
||||
public List<Stmt> ThenStmts=new();
|
||||
public List<Stmt> ElseStmts=new();
|
||||
}
|
||||
public class WhileStmt:Stmt{
|
||||
required public Expr Cond;
|
||||
public List<Stmt> Body=new();
|
||||
}
|
||||
public class ForStmt:Stmt{
|
||||
required public string Var;
|
||||
required public Expr Start;
|
||||
required public Expr End;
|
||||
public Expr Step = new IntExpr(1);
|
||||
public List<Stmt> Body=new();
|
||||
}
|
||||
|
||||
public abstract class Expr:StNode {
|
||||
public VarType Type; // Speichert den Typ des Ausdrucks
|
||||
}
|
||||
public class IntExpr:Expr {
|
||||
public long Value;
|
||||
public IntExpr(long v, VarType type = VarType.DINT) {
|
||||
Value = v;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
public class RealExpr:Expr {
|
||||
public double Value;
|
||||
public RealExpr(double v, VarType type = VarType.REAL) {
|
||||
Value = v;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
public class VarExpr:Expr {
|
||||
public string Name;
|
||||
public VarExpr(string n, VarType type) {
|
||||
Name = n;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
public class BinaryExpr:Expr {
|
||||
public Expr L;
|
||||
public Expr R;
|
||||
public TokType Op;
|
||||
public BinaryExpr(Expr l, TokType op, Expr r) {
|
||||
L = l;
|
||||
Op = op;
|
||||
R = r;
|
||||
Type = DetermineResultType(l.Type, r.Type);
|
||||
}
|
||||
|
||||
private static VarType DetermineResultType(VarType left, VarType right) {
|
||||
// Wenn einer der Operanden LREAL ist, ist das Ergebnis LREAL
|
||||
if (left == VarType.LREAL || right == VarType.LREAL)
|
||||
return VarType.LREAL;
|
||||
// Wenn einer der Operanden REAL ist, ist das Ergebnis REAL
|
||||
if (left == VarType.REAL || right == VarType.REAL)
|
||||
return VarType.REAL;
|
||||
// Bei gemischten Integer-Typen nehmen wir den größeren
|
||||
if ((int)left > (int)right)
|
||||
return left;
|
||||
return right;
|
||||
}
|
||||
}
|
||||
|
||||
// === TOKENIZER ===
|
||||
public enum TokType {
|
||||
IDENT, INT, REAL, ASSIGN, SEMI, LPAREN, RPAREN,
|
||||
PLUS, MINUS, MUL, DIV,
|
||||
LT, GT, LE, GE, EQ, NEQ,
|
||||
IF, THEN, ELSE, END_IF,
|
||||
WHILE, DO, END_WHILE,
|
||||
FOR, TO, BY, END_FOR,
|
||||
PROGRAM, VAR, END_VAR, END_PROGRAM,
|
||||
EOF
|
||||
}
|
||||
public class Token{
|
||||
public TokType Type;
|
||||
public string Text;
|
||||
public int Line;
|
||||
public Token(TokType t, string s, int line) { Type=t; Text=s; Line=line; }
|
||||
}
|
||||
|
||||
public class CompileError {
|
||||
public int Line;
|
||||
public string Message;
|
||||
public CompileError(int line, string msg) { Line=line; Message=msg; }
|
||||
}
|
||||
|
||||
public class StLexer {
|
||||
private readonly string src;
|
||||
private int i;
|
||||
private int currentLine = 1;
|
||||
public List<CompileError> Errors = new();
|
||||
public StLexer(string s){src=s;}
|
||||
char Peek()=> i<src.Length?src[i]:'\0';
|
||||
char Next(){
|
||||
if (i >= src.Length) return '\0';
|
||||
char c = src[i++];
|
||||
if (c == '\n') currentLine++;
|
||||
return c;
|
||||
}
|
||||
|
||||
void AddError(string msg) => Errors.Add(new CompileError(currentLine, msg));
|
||||
|
||||
public Token NextToken() {
|
||||
while (char.IsWhiteSpace(Peek())) Next();
|
||||
if (Peek()=='\0') return new Token(TokType.EOF,"", currentLine);
|
||||
|
||||
if (char.IsLetter(Peek())||Peek()=='_'){
|
||||
var sb=new StringBuilder();
|
||||
int startLine = currentLine;
|
||||
while (char.IsLetterOrDigit(Peek())||Peek()=='_') sb.Append(Next());
|
||||
var s=sb.ToString().ToUpperInvariant();
|
||||
return s switch {
|
||||
"PROGRAM"=>new Token(TokType.PROGRAM,s,startLine),
|
||||
"VAR"=>new Token(TokType.VAR,s,startLine),
|
||||
"END_VAR"=>new Token(TokType.END_VAR,s,startLine),
|
||||
"END_PROGRAM"=>new Token(TokType.END_PROGRAM,s,startLine),
|
||||
"IF"=>new Token(TokType.IF,s,startLine),
|
||||
"THEN"=>new Token(TokType.THEN,s,startLine),
|
||||
"ELSE"=>new Token(TokType.ELSE,s,startLine),
|
||||
"END_IF"=>new Token(TokType.END_IF,s,startLine),
|
||||
"WHILE"=>new Token(TokType.WHILE,s,startLine),
|
||||
"DO"=>new Token(TokType.DO,s,startLine),
|
||||
"END_WHILE"=>new Token(TokType.END_WHILE,s,startLine),
|
||||
"FOR"=>new Token(TokType.FOR,s,startLine),
|
||||
"TO"=>new Token(TokType.TO,s,startLine),
|
||||
"BY"=>new Token(TokType.BY,s,startLine),
|
||||
"END_FOR"=>new Token(TokType.END_FOR,s,startLine),
|
||||
_=>new Token(TokType.IDENT,s,startLine)
|
||||
};
|
||||
}
|
||||
|
||||
if (char.IsDigit(Peek())) {
|
||||
var sb = new StringBuilder();
|
||||
int startLine = currentLine;
|
||||
bool isFloat = false;
|
||||
|
||||
// Ganze Zahl vor dem Dezimalpunkt
|
||||
while(char.IsDigit(Peek()))
|
||||
sb.Append(Next());
|
||||
|
||||
// Optional: Dezimalpunkt und Nachkommastellen
|
||||
if (Peek() == '.') {
|
||||
isFloat = true;
|
||||
sb.Append(Next());
|
||||
while(char.IsDigit(Peek()))
|
||||
sb.Append(Next());
|
||||
}
|
||||
|
||||
// Optional: Exponentialdarstellung
|
||||
if (Peek() == 'E' || Peek() == 'e') {
|
||||
isFloat = true;
|
||||
sb.Append(Next());
|
||||
if (Peek() == '+' || Peek() == '-')
|
||||
sb.Append(Next());
|
||||
if (!char.IsDigit(Peek())) {
|
||||
AddError("Expected digits after exponent");
|
||||
return new Token(TokType.EOF, "", startLine);
|
||||
}
|
||||
while(char.IsDigit(Peek()))
|
||||
sb.Append(Next());
|
||||
}
|
||||
|
||||
return new Token(isFloat ? TokType.REAL : TokType.INT, sb.ToString(), startLine);
|
||||
}
|
||||
|
||||
int tokenLine = currentLine;
|
||||
if (Peek()==':'){
|
||||
Next();
|
||||
if(Peek()=='='){
|
||||
Next();
|
||||
return new Token(TokType.ASSIGN,":=",tokenLine);
|
||||
}
|
||||
AddError("Expected '=' after ':' for assignment");
|
||||
// Bei einem einzelnen ':' geben wir EOF zurück und stoppen das Parsen
|
||||
i--; // Gehen einen Schritt zurück, damit der fehlerhafte ':' Token beim nächsten Mal neu gelesen wird
|
||||
return new Token(TokType.EOF,"",tokenLine);
|
||||
}
|
||||
if (Peek()=='<'){
|
||||
Next();
|
||||
if (Peek()=='='){Next(); return new Token(TokType.LE,"<=",tokenLine);}
|
||||
if (Peek()=='>'){Next(); return new Token(TokType.NEQ,"<>",tokenLine);}
|
||||
return new Token(TokType.LT,"<",tokenLine);
|
||||
}
|
||||
if (Peek()=='>'){
|
||||
Next();
|
||||
if (Peek()=='='){Next(); return new Token(TokType.GE,">=",tokenLine);}
|
||||
return new Token(TokType.GT,">",tokenLine);
|
||||
}
|
||||
if (Peek()=='='){Next();return new Token(TokType.EQ,"=",tokenLine);}
|
||||
|
||||
char c=Next();
|
||||
if (c == ';') return new Token(TokType.SEMI,";",tokenLine);
|
||||
if (c == '(') return new Token(TokType.LPAREN,"(",tokenLine);
|
||||
if (c == ')') return new Token(TokType.RPAREN,")",tokenLine);
|
||||
if (c == '+') return new Token(TokType.PLUS,"+",tokenLine);
|
||||
if (c == '-') return new Token(TokType.MINUS,"-",tokenLine);
|
||||
if (c == '*') return new Token(TokType.MUL,"*",tokenLine);
|
||||
if (c == '/') return new Token(TokType.DIV,"/",tokenLine);
|
||||
|
||||
AddError($"Unexpected character '{c}'");
|
||||
return new Token(TokType.EOF,"",tokenLine); // Skip invalid character
|
||||
}
|
||||
}
|
||||
|
||||
// === PARSER ===
|
||||
public record Symbol {
|
||||
required public string Name;
|
||||
public VarType Type;
|
||||
public int Index;
|
||||
}
|
||||
|
||||
public class StParser {
|
||||
StLexer lex;
|
||||
Token cur;
|
||||
Dictionary<string,Symbol> syms = new();
|
||||
public List<CompileError> Errors => lex.Errors;
|
||||
public bool HasErrors => Errors.Count > 0;
|
||||
|
||||
public StParser(string s){
|
||||
lex=new StLexer(s);
|
||||
cur=lex.NextToken();
|
||||
}
|
||||
|
||||
void Next()=>cur=lex.NextToken();
|
||||
|
||||
void AddError(string msg) => lex.Errors.Add(new CompileError(cur.Line, msg));
|
||||
|
||||
bool Expect(TokType t){
|
||||
if(cur.Type!=t) {
|
||||
AddError($"Expected {t}, got {cur.Type}");
|
||||
return false;
|
||||
}
|
||||
Next();
|
||||
return true;
|
||||
}
|
||||
|
||||
public ProgramNode? ParseProgram(){
|
||||
var p=new ProgramNode();
|
||||
if (!Expect(TokType.PROGRAM)) return null;
|
||||
|
||||
if(cur.Type==TokType.IDENT) Next();
|
||||
|
||||
if(cur.Type==TokType.VAR){
|
||||
Next();
|
||||
while(cur.Type==TokType.IDENT) {
|
||||
var varDecl = ParseVarDecl();
|
||||
if (varDecl == null) return null;
|
||||
p.Vars.Add(varDecl);
|
||||
}
|
||||
if (!Expect(TokType.END_VAR)) return null;
|
||||
}
|
||||
|
||||
while(cur.Type!=TokType.END_PROGRAM && cur.Type!=TokType.EOF) {
|
||||
var stmt = ParseStmt();
|
||||
if (stmt == null) return null;
|
||||
p.Stmts.Add(stmt);
|
||||
}
|
||||
|
||||
if (!Expect(TokType.END_PROGRAM)) return null;
|
||||
return p;
|
||||
}
|
||||
|
||||
VarDecl? ParseVarDecl(){
|
||||
if (cur.Type != TokType.IDENT) {
|
||||
AddError("Expected identifier for variable declaration");
|
||||
return null;
|
||||
}
|
||||
string name=cur.Text.ToUpperInvariant(); // Variablennamen in Großbuchstaben
|
||||
Next();
|
||||
|
||||
if (cur.Type != TokType.IDENT) {
|
||||
AddError("Expected type name");
|
||||
return null;
|
||||
}
|
||||
string tname=cur.Text.ToLowerInvariant();
|
||||
Next();
|
||||
|
||||
VarType? vt = tname switch {
|
||||
// Boolean
|
||||
"bool" => VarType.BOOL,
|
||||
// Unsigned integers
|
||||
"byte" => VarType.BYTE,
|
||||
"word" => VarType.WORD,
|
||||
"dword" => VarType.DWORD,
|
||||
"lword" => VarType.LWORD,
|
||||
// Signed integers
|
||||
"sint" => VarType.SINT,
|
||||
"int" => VarType.INT,
|
||||
"dint" => VarType.DINT,
|
||||
"lint" => VarType.LINT,
|
||||
// Unsigned integers (alternative names)
|
||||
"usint" => VarType.USINT,
|
||||
"uint" => VarType.UINT,
|
||||
"udint" => VarType.UDINT,
|
||||
"ulint" => VarType.ULINT,
|
||||
// Floating point
|
||||
"real" => VarType.REAL,
|
||||
"lreal" => VarType.LREAL,
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (vt == null) {
|
||||
AddError($"Unknown type '{tname}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
Expr? init=null;
|
||||
if(cur.Type==TokType.ASSIGN){
|
||||
Next(); // consume :=
|
||||
init=ParseExpr();
|
||||
if (init == null) {
|
||||
AddError($"Expected expression after ':=' in variable declaration");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Expect(TokType.SEMI)) return null;
|
||||
|
||||
// Füge Variable zur Symboltabelle hinzu
|
||||
syms[name] = new Symbol { Name = name, Type = vt.Value };
|
||||
|
||||
return new VarDecl{Name=name,Type=vt.Value,Init=init};
|
||||
}
|
||||
|
||||
Stmt? ParseAssign() {
|
||||
// Der Aufrufer hat bereits geprüft, dass wir bei einem IDENT sind
|
||||
string target = cur.Text.ToUpperInvariant(); // Variablennamen in Großbuchstaben
|
||||
Next(); // consume identifier
|
||||
if (cur.Type != TokType.ASSIGN) {
|
||||
AddError($"Expected ':=' after identifier '{target}'");
|
||||
return null;
|
||||
}
|
||||
Next(); // consume :=
|
||||
var e = ParseExpr();
|
||||
if (e == null) return null;
|
||||
if (!Expect(TokType.SEMI)) return null;
|
||||
return new AssignStmt{Target=target, Expr=e};
|
||||
}
|
||||
|
||||
Stmt? ParseStmt(){
|
||||
switch(cur.Type) {
|
||||
case TokType.IF: return ParseIf();
|
||||
case TokType.WHILE: return ParseWhile();
|
||||
case TokType.FOR: return ParseFor();
|
||||
case TokType.IDENT:
|
||||
return ParseAssign();
|
||||
default:
|
||||
AddError($"Unexpected token {cur.Type} in statement");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
IfStmt? ParseIf(){
|
||||
Next(); // IF
|
||||
var cond=ParseExpr();
|
||||
if (cond == null) return null;
|
||||
if (!Expect(TokType.THEN)) return null;
|
||||
|
||||
var node=new IfStmt{Cond=cond};
|
||||
while(cur.Type!=TokType.ELSE && cur.Type!=TokType.END_IF && cur.Type!=TokType.EOF) {
|
||||
var stmt = ParseStmt();
|
||||
if (stmt == null) return null;
|
||||
node.ThenStmts.Add(stmt);
|
||||
}
|
||||
|
||||
if(cur.Type==TokType.ELSE){
|
||||
Next();
|
||||
while(cur.Type!=TokType.END_IF && cur.Type!=TokType.EOF) {
|
||||
var stmt = ParseStmt();
|
||||
if (stmt == null) return null;
|
||||
node.ElseStmts.Add(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Expect(TokType.END_IF)) return null;
|
||||
if (!Expect(TokType.SEMI)) return null;
|
||||
return node;
|
||||
}
|
||||
|
||||
WhileStmt? ParseWhile(){
|
||||
Next(); // WHILE
|
||||
var cond=ParseExpr();
|
||||
if (cond == null) return null;
|
||||
if (!Expect(TokType.DO)) return null;
|
||||
|
||||
var ws=new WhileStmt{Cond=cond};
|
||||
while(cur.Type!=TokType.END_WHILE && cur.Type!=TokType.EOF) {
|
||||
var stmt = ParseStmt();
|
||||
if (stmt == null) return null;
|
||||
ws.Body.Add(stmt);
|
||||
}
|
||||
|
||||
if (!Expect(TokType.END_WHILE)) return null;
|
||||
if (!Expect(TokType.SEMI)) return null;
|
||||
return ws;
|
||||
}
|
||||
|
||||
ForStmt? ParseFor(){
|
||||
Next(); // FOR
|
||||
if (cur.Type != TokType.IDENT) {
|
||||
AddError("Expected identifier for FOR loop variable");
|
||||
return null;
|
||||
}
|
||||
string varName = cur.Text.ToUpperInvariant(); // Variablennamen in Großbuchstaben
|
||||
Next(); // consume identifier
|
||||
|
||||
if (cur.Type != TokType.ASSIGN) {
|
||||
AddError($"Expected ':=' after identifier '{varName}'");
|
||||
return null;
|
||||
}
|
||||
Next(); // consume :=
|
||||
var start = ParseExpr();
|
||||
if (start == null) return null;
|
||||
|
||||
if (!Expect(TokType.TO)) return null;
|
||||
var end = ParseExpr();
|
||||
if (end == null) return null;
|
||||
|
||||
Expr step = new IntExpr(1);
|
||||
if(cur.Type==TokType.BY){
|
||||
Next();
|
||||
step = ParseExpr() ?? step;
|
||||
}
|
||||
|
||||
if (!Expect(TokType.DO)) return null;
|
||||
|
||||
var fs = new ForStmt{Var=varName, Start=start, End=end, Step=step};
|
||||
while(cur.Type!=TokType.END_FOR && cur.Type!=TokType.EOF) {
|
||||
var stmt = ParseStmt();
|
||||
if (stmt == null) return null;
|
||||
fs.Body.Add(stmt);
|
||||
}
|
||||
|
||||
if (!Expect(TokType.END_FOR)) return null;
|
||||
if (!Expect(TokType.SEMI)) return null;
|
||||
return fs;
|
||||
}
|
||||
|
||||
Expr? ParseExpr() => ParseCompare();
|
||||
|
||||
Expr? ParseCompare(){
|
||||
var l = ParseAddSub();
|
||||
if (l == null) return null;
|
||||
|
||||
while(cur.Type is TokType.LT or TokType.GT or TokType.LE or TokType.GE or TokType.EQ or TokType.NEQ){
|
||||
var op=cur.Type;
|
||||
Next();
|
||||
var r=ParseAddSub();
|
||||
if (r == null) return null;
|
||||
l=new BinaryExpr(l,op,r);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
Expr? ParseAddSub(){
|
||||
var l=ParseMulDiv();
|
||||
if (l == null) return null;
|
||||
|
||||
while(cur.Type==TokType.PLUS||cur.Type==TokType.MINUS){
|
||||
var op=cur.Type;
|
||||
Next();
|
||||
var r=ParseMulDiv();
|
||||
if (r == null) return null;
|
||||
l=new BinaryExpr(l,op,r);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
Expr? ParseMulDiv(){
|
||||
var l=ParsePrimary();
|
||||
if (l == null) return null;
|
||||
|
||||
while(cur.Type==TokType.MUL||cur.Type==TokType.DIV){
|
||||
var op=cur.Type;
|
||||
Next();
|
||||
var r=ParsePrimary();
|
||||
if (r == null) return null;
|
||||
l=new BinaryExpr(l,op,r);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
Expr? ParsePrimary(){
|
||||
int startLine = cur.Line;
|
||||
switch(cur.Type) {
|
||||
case TokType.INT:
|
||||
if (!long.TryParse(cur.Text, out var v)) {
|
||||
AddError($"Invalid integer literal '{cur.Text}'");
|
||||
return null;
|
||||
}
|
||||
Next();
|
||||
return new IntExpr(v, VarType.DINT);
|
||||
|
||||
case TokType.REAL:
|
||||
if (!double.TryParse(cur.Text, out var d)) {
|
||||
AddError($"Invalid floating point literal '{cur.Text}'");
|
||||
return null;
|
||||
}
|
||||
Next();
|
||||
return new RealExpr(d);
|
||||
|
||||
case TokType.IDENT:
|
||||
string n = cur.Text.ToUpperInvariant(); // Variablennamen in Großbuchstaben
|
||||
Next();
|
||||
Symbol? sym;
|
||||
if (!syms.TryGetValue(n, out sym)) {
|
||||
AddError($"Undeclared variable '{n}'");
|
||||
return null;
|
||||
}
|
||||
return new VarExpr(n, sym.Type);
|
||||
|
||||
case TokType.LPAREN:
|
||||
Next();
|
||||
var e = ParseExpr();
|
||||
if (e == null) return null;
|
||||
if (!Expect(TokType.RPAREN)) return null;
|
||||
return e;
|
||||
|
||||
default:
|
||||
AddError($"Unexpected token {cur.Type} in expression");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === BYTECODE ===
|
||||
public class BytecodeEmitter {
|
||||
List<object> consts = new(); // Kann nun int, long, float oder double speichern
|
||||
Dictionary<string,Symbol> syms = new();
|
||||
List<byte> code = new();
|
||||
|
||||
class Symbol {
|
||||
required public string Name;
|
||||
public VarType Type;
|
||||
public int Index;
|
||||
}
|
||||
|
||||
public int ConstantsCount => consts.Count;
|
||||
public int VarCount => syms.Count;
|
||||
public int CodeLength => code.Count;
|
||||
|
||||
public void Compile(ProgramNode p){
|
||||
int idx=0;
|
||||
foreach(var v in p.Vars)
|
||||
syms[v.Name]=new Symbol{Name=v.Name,Type=v.Type,Index=idx++};
|
||||
|
||||
foreach(var v in p.Vars)
|
||||
if(v.Init!=null){EmitExpr(v.Init);EmitByte(0x03);EmitU16((ushort)syms[v.Name].Index);}
|
||||
|
||||
foreach(var s in p.Stmts)
|
||||
EmitStmt(s);
|
||||
|
||||
EmitByte(0xF0); // Program End
|
||||
}
|
||||
|
||||
// Operationscodes für verschiedene Datentypen
|
||||
Dictionary<(TokType, VarType), byte> opCodes = new() {
|
||||
// Signed integer arithmetic
|
||||
{(TokType.PLUS, VarType.SINT), Bytecode.OpCodes.ADD_SINT}, {(TokType.MINUS, VarType.SINT), Bytecode.OpCodes.SUB_SINT},
|
||||
{(TokType.MUL, VarType.SINT), Bytecode.OpCodes.MUL_SINT}, {(TokType.DIV, VarType.SINT), Bytecode.OpCodes.DIV_SINT},
|
||||
{(TokType.PLUS, VarType.INT), Bytecode.OpCodes.ADD_INT}, {(TokType.MINUS, VarType.INT), Bytecode.OpCodes.SUB_INT},
|
||||
{(TokType.MUL, VarType.INT), Bytecode.OpCodes.MUL_INT}, {(TokType.DIV, VarType.INT), Bytecode.OpCodes.DIV_INT},
|
||||
{(TokType.PLUS, VarType.DINT), Bytecode.OpCodes.ADD_DINT}, {(TokType.MINUS, VarType.DINT), Bytecode.OpCodes.SUB_DINT},
|
||||
{(TokType.MUL, VarType.DINT), Bytecode.OpCodes.MUL_DINT}, {(TokType.DIV, VarType.DINT), Bytecode.OpCodes.DIV_DINT},
|
||||
{(TokType.PLUS, VarType.LINT), Bytecode.OpCodes.ADD_LINT}, {(TokType.MINUS, VarType.LINT), Bytecode.OpCodes.SUB_LINT},
|
||||
{(TokType.MUL, VarType.LINT), Bytecode.OpCodes.MUL_LINT}, {(TokType.DIV, VarType.LINT), Bytecode.OpCodes.DIV_LINT},
|
||||
|
||||
// Unsigned integer arithmetic
|
||||
{(TokType.PLUS, VarType.USINT), Bytecode.OpCodes.ADD_USINT}, {(TokType.MINUS, VarType.USINT), Bytecode.OpCodes.SUB_USINT},
|
||||
{(TokType.MUL, VarType.USINT), Bytecode.OpCodes.MUL_USINT}, {(TokType.DIV, VarType.USINT), Bytecode.OpCodes.DIV_USINT},
|
||||
{(TokType.PLUS, VarType.UINT), Bytecode.OpCodes.ADD_UINT}, {(TokType.MINUS, VarType.UINT), Bytecode.OpCodes.SUB_UINT},
|
||||
{(TokType.MUL, VarType.UINT), Bytecode.OpCodes.MUL_UINT}, {(TokType.DIV, VarType.UINT), Bytecode.OpCodes.DIV_UINT},
|
||||
{(TokType.PLUS, VarType.UDINT), Bytecode.OpCodes.ADD_UDINT}, {(TokType.MINUS, VarType.UDINT), Bytecode.OpCodes.SUB_UDINT},
|
||||
{(TokType.MUL, VarType.UDINT), Bytecode.OpCodes.MUL_UDINT}, {(TokType.DIV, VarType.UDINT), Bytecode.OpCodes.DIV_UDINT},
|
||||
{(TokType.PLUS, VarType.ULINT), Bytecode.OpCodes.ADD_ULINT}, {(TokType.MINUS, VarType.ULINT), Bytecode.OpCodes.SUB_ULINT},
|
||||
{(TokType.MUL, VarType.ULINT), Bytecode.OpCodes.MUL_ULINT}, {(TokType.DIV, VarType.ULINT), Bytecode.OpCodes.DIV_ULINT},
|
||||
|
||||
// Floating point arithmetic
|
||||
{(TokType.PLUS, VarType.REAL), Bytecode.OpCodes.ADD_REAL}, {(TokType.MINUS, VarType.REAL), Bytecode.OpCodes.SUB_REAL},
|
||||
{(TokType.MUL, VarType.REAL), Bytecode.OpCodes.MUL_REAL}, {(TokType.DIV, VarType.REAL), Bytecode.OpCodes.DIV_REAL},
|
||||
{(TokType.PLUS, VarType.LREAL), Bytecode.OpCodes.ADD_LREAL}, {(TokType.MINUS, VarType.LREAL), Bytecode.OpCodes.SUB_LREAL},
|
||||
{(TokType.MUL, VarType.LREAL), Bytecode.OpCodes.MUL_LREAL}, {(TokType.DIV, VarType.LREAL), Bytecode.OpCodes.DIV_LREAL},
|
||||
|
||||
// Comparisons signed
|
||||
{(TokType.LT, VarType.SINT), Bytecode.OpCodes.LT_S}, {(TokType.GT, VarType.SINT), Bytecode.OpCodes.GT_S},
|
||||
{(TokType.LE, VarType.SINT), Bytecode.OpCodes.LE_S}, {(TokType.GE, VarType.SINT), Bytecode.OpCodes.GE_S},
|
||||
{(TokType.EQ, VarType.SINT), Bytecode.OpCodes.EQ_S}, {(TokType.NEQ, VarType.SINT), Bytecode.OpCodes.NEQ_S},
|
||||
{(TokType.LT, VarType.INT), Bytecode.OpCodes.LT_S}, {(TokType.GT, VarType.INT), Bytecode.OpCodes.GT_S},
|
||||
{(TokType.LE, VarType.INT), Bytecode.OpCodes.LE_S}, {(TokType.GE, VarType.INT), Bytecode.OpCodes.GE_S},
|
||||
{(TokType.EQ, VarType.INT), Bytecode.OpCodes.EQ_S}, {(TokType.NEQ, VarType.INT), Bytecode.OpCodes.NEQ_S},
|
||||
{(TokType.LT, VarType.DINT), Bytecode.OpCodes.LT_S}, {(TokType.GT, VarType.DINT), Bytecode.OpCodes.GT_S},
|
||||
{(TokType.LE, VarType.DINT), Bytecode.OpCodes.LE_S}, {(TokType.GE, VarType.DINT), Bytecode.OpCodes.GE_S},
|
||||
{(TokType.EQ, VarType.DINT), Bytecode.OpCodes.EQ_S}, {(TokType.NEQ, VarType.DINT), Bytecode.OpCodes.NEQ_S},
|
||||
{(TokType.LT, VarType.LINT), Bytecode.OpCodes.LT_S}, {(TokType.GT, VarType.LINT), Bytecode.OpCodes.GT_S},
|
||||
{(TokType.LE, VarType.LINT), Bytecode.OpCodes.LE_S}, {(TokType.GE, VarType.LINT), Bytecode.OpCodes.GE_S},
|
||||
{(TokType.EQ, VarType.LINT), Bytecode.OpCodes.EQ_S}, {(TokType.NEQ, VarType.LINT), Bytecode.OpCodes.NEQ_S},
|
||||
|
||||
// Comparisons unsigned
|
||||
{(TokType.LT, VarType.USINT), Bytecode.OpCodes.LT_U}, {(TokType.GT, VarType.USINT), Bytecode.OpCodes.GT_U},
|
||||
{(TokType.LE, VarType.USINT), Bytecode.OpCodes.LE_U}, {(TokType.GE, VarType.USINT), Bytecode.OpCodes.GE_U},
|
||||
{(TokType.EQ, VarType.USINT), Bytecode.OpCodes.EQ_U}, {(TokType.NEQ, VarType.USINT), Bytecode.OpCodes.NEQ_U},
|
||||
{(TokType.LT, VarType.UINT), Bytecode.OpCodes.LT_U}, {(TokType.GT, VarType.UINT), Bytecode.OpCodes.GT_U},
|
||||
{(TokType.LE, VarType.UINT), Bytecode.OpCodes.LE_U}, {(TokType.GE, VarType.UINT), Bytecode.OpCodes.GE_U},
|
||||
{(TokType.EQ, VarType.UINT), Bytecode.OpCodes.EQ_U}, {(TokType.NEQ, VarType.UINT), Bytecode.OpCodes.NEQ_U},
|
||||
{(TokType.LT, VarType.UDINT), Bytecode.OpCodes.LT_U}, {(TokType.GT, VarType.UDINT), Bytecode.OpCodes.GT_U},
|
||||
{(TokType.LE, VarType.UDINT), Bytecode.OpCodes.LE_U}, {(TokType.GE, VarType.UDINT), Bytecode.OpCodes.GE_U},
|
||||
{(TokType.EQ, VarType.UDINT), Bytecode.OpCodes.EQ_U}, {(TokType.NEQ, VarType.UDINT), Bytecode.OpCodes.NEQ_U},
|
||||
{(TokType.LT, VarType.ULINT), Bytecode.OpCodes.LT_U}, {(TokType.GT, VarType.ULINT), Bytecode.OpCodes.GT_U},
|
||||
{(TokType.LE, VarType.ULINT), Bytecode.OpCodes.LE_U}, {(TokType.GE, VarType.ULINT), Bytecode.OpCodes.GE_U},
|
||||
{(TokType.EQ, VarType.ULINT), Bytecode.OpCodes.EQ_U}, {(TokType.NEQ, VarType.ULINT), Bytecode.OpCodes.NEQ_U},
|
||||
|
||||
// Comparisons floating
|
||||
{(TokType.LT, VarType.REAL), Bytecode.OpCodes.LT_F}, {(TokType.GT, VarType.REAL), Bytecode.OpCodes.GT_F},
|
||||
{(TokType.LE, VarType.REAL), Bytecode.OpCodes.LE_F}, {(TokType.GE, VarType.REAL), Bytecode.OpCodes.GE_F},
|
||||
{(TokType.EQ, VarType.REAL), Bytecode.OpCodes.EQ_F}, {(TokType.NEQ, VarType.REAL), Bytecode.OpCodes.NEQ_F},
|
||||
{(TokType.LT, VarType.LREAL), Bytecode.OpCodes.LT_F}, {(TokType.GT, VarType.LREAL), Bytecode.OpCodes.GT_F},
|
||||
{(TokType.LE, VarType.LREAL), Bytecode.OpCodes.LE_F}, {(TokType.GE, VarType.LREAL), Bytecode.OpCodes.GE_F},
|
||||
{(TokType.EQ, VarType.LREAL), Bytecode.OpCodes.EQ_F}, {(TokType.NEQ, VarType.LREAL), Bytecode.OpCodes.NEQ_F}
|
||||
};
|
||||
|
||||
void EmitStmt(Stmt s){
|
||||
switch(s){
|
||||
case AssignStmt a:
|
||||
Symbol? symbol = null;
|
||||
if (!syms.TryGetValue(a.Target, out symbol)) {
|
||||
throw new Exception($"Undeclared variable '{a.Target}'");
|
||||
}
|
||||
EmitExpr(a.Expr);
|
||||
EmitByte(Bytecode.OpCodes.STORE_VAR); EmitU16((ushort)symbol.Index);
|
||||
break;
|
||||
|
||||
case IfStmt iff:
|
||||
EmitExpr(iff.Cond);
|
||||
EmitByte(Bytecode.OpCodes.JZ); int jz=code.Count; EmitU16(0);
|
||||
foreach(var st in iff.ThenStmts) EmitStmt(st);
|
||||
if(iff.ElseStmts.Count>0){
|
||||
EmitByte(Bytecode.OpCodes.JMP); int jmp=code.Count; EmitU16(0);
|
||||
PatchJump(jz,code.Count);
|
||||
foreach(var st in iff.ElseStmts) EmitStmt(st);
|
||||
PatchJump(jmp,code.Count);
|
||||
} else PatchJump(jz,code.Count);
|
||||
break;
|
||||
|
||||
case WhileStmt w:
|
||||
int loopStart=code.Count;
|
||||
EmitExpr(w.Cond);
|
||||
EmitByte(Bytecode.OpCodes.JZ); int jzpos=code.Count; EmitU16(0);
|
||||
foreach(var st in w.Body) EmitStmt(st);
|
||||
EmitByte(Bytecode.OpCodes.JMP); EmitU16((ushort)loopStart);
|
||||
PatchJump(jzpos,code.Count);
|
||||
break;
|
||||
|
||||
case ForStmt f:
|
||||
Symbol? forSymbol = null;
|
||||
if (!syms.TryGetValue(f.Var, out forSymbol)) {
|
||||
throw new Exception($"Undeclared variable '{f.Var}'");
|
||||
}
|
||||
// Initialisierung: var := start
|
||||
EmitExpr(f.Start);
|
||||
EmitByte(Bytecode.OpCodes.STORE_VAR); EmitU16((ushort)forSymbol.Index);
|
||||
|
||||
int cmpPos = code.Count; // Position des Vergleichs
|
||||
EmitExpr(new VarExpr(f.Var, forSymbol.Type));
|
||||
EmitExpr(f.End);
|
||||
var key = (TokType.LE, forSymbol.Type);
|
||||
if (!opCodes.ContainsKey(key)) {
|
||||
throw new Exception($"Comparison not supported for type {forSymbol.Type}");
|
||||
}
|
||||
EmitByte(opCodes[key]);
|
||||
EmitByte(Bytecode.OpCodes.JZ); int jzFor = code.Count; EmitU16(0); // Jump zum Ende
|
||||
|
||||
// Body
|
||||
foreach(var st in f.Body) EmitStmt(st);
|
||||
|
||||
// Inkrement: i := i + step
|
||||
EmitExpr(new VarExpr(f.Var, forSymbol.Type));
|
||||
EmitExpr(f.Step);
|
||||
var addKey = (TokType.PLUS, forSymbol.Type);
|
||||
if (!opCodes.ContainsKey(addKey)) {
|
||||
throw new Exception($"Addition not supported for type {forSymbol.Type}");
|
||||
}
|
||||
EmitByte(opCodes[addKey]);
|
||||
EmitByte(Bytecode.OpCodes.STORE_VAR); EmitU16((ushort)forSymbol.Index);
|
||||
|
||||
// Vergleich erneut, aber wir merken uns den Sprung zum Vergleich
|
||||
EmitByte(Bytecode.OpCodes.JMP); EmitU16((ushort)cmpPos);
|
||||
|
||||
// Patch Jump: Ende der Schleife springt hierhin
|
||||
PatchJump(jzFor, code.Count);
|
||||
|
||||
// Korrektur: Schleifenvariable auf Endwert, falls sie überläuft
|
||||
EmitExpr(f.End);
|
||||
EmitByte(Bytecode.OpCodes.STORE_VAR); EmitU16((ushort)syms[f.Var].Index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PatchJump(int pos,int target){code[pos]=(byte)(target&0xFF);code[pos+1]=(byte)(target>>8);}
|
||||
void EmitExpr(Expr e){
|
||||
switch(e){
|
||||
case IntExpr ie:
|
||||
int ci = AddConst(ie.Value);
|
||||
EmitByte(Bytecode.OpCodes.PUSH_CONST); // PUSH_CONST
|
||||
EmitU16((ushort)ci);
|
||||
EmitByte((byte)ie.Type); // Typ der Konstante
|
||||
break;
|
||||
|
||||
case RealExpr re:
|
||||
int cri = AddConst(re.Value);
|
||||
EmitByte(Bytecode.OpCodes.PUSH_REAL_CONST); // PUSH_REAL_CONST
|
||||
EmitU16((ushort)cri);
|
||||
EmitByte((byte)re.Type); // REAL oder LREAL
|
||||
break;
|
||||
|
||||
case VarExpr ve:
|
||||
Symbol? symbol = null;
|
||||
if (!syms.TryGetValue(ve.Name, out symbol)) {
|
||||
throw new Exception($"Undeclared variable '{ve.Name}'");
|
||||
}
|
||||
EmitByte(Bytecode.OpCodes.LOAD_VAR); // LOAD_VAR
|
||||
EmitU16((ushort)symbol.Index);
|
||||
break;
|
||||
|
||||
case BinaryExpr be:
|
||||
EmitExpr(be.L);
|
||||
EmitExpr(be.R);
|
||||
|
||||
var key = (be.Op, be.Type);
|
||||
if (!opCodes.ContainsKey(key)) {
|
||||
throw new Exception($"Unknown operator '{be.Op}' for type {be.Type}");
|
||||
}
|
||||
|
||||
// Wenn nötig, Typenkonvertierung vor der Operation
|
||||
if (be.L.Type != be.Type)
|
||||
EmitByte((byte)(0x50 + (int)be.Type)); // CONVERT_TO_*
|
||||
if (be.R.Type != be.Type)
|
||||
EmitByte((byte)(0x50 + (int)be.Type)); // CONVERT_TO_*
|
||||
|
||||
EmitByte(opCodes[key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int AddConst(object v) {
|
||||
int i = consts.FindIndex(c => c.Equals(v));
|
||||
if (i >= 0) return i;
|
||||
consts.Add(v);
|
||||
return consts.Count - 1;
|
||||
}
|
||||
|
||||
void EmitByte(byte b) => code.Add(b);
|
||||
void EmitU16(ushort v) {code.Add((byte)(v&0xFF));code.Add((byte)(v>>8));}
|
||||
|
||||
public byte[] BuildBinary() {
|
||||
using var ms = new MemoryStream();
|
||||
var w = new BinaryWriter(ms);
|
||||
|
||||
// Header
|
||||
w.Write(Encoding.ASCII.GetBytes(Bytecode.Magic));
|
||||
w.Write(Bytecode.Version);
|
||||
|
||||
// Konstanten
|
||||
w.Write((ushort)consts.Count);
|
||||
foreach(var c in consts) {
|
||||
if (c is long l) {
|
||||
w.Write((byte)1); // Long type marker
|
||||
w.Write(l);
|
||||
}
|
||||
else if (c is double d) {
|
||||
w.Write((byte)2); // Double type marker
|
||||
w.Write(d);
|
||||
}
|
||||
else if (c is float f) {
|
||||
w.Write((byte)3); // Float type marker
|
||||
w.Write(f);
|
||||
}
|
||||
else if (c is int i) {
|
||||
w.Write((byte)4); // Int type marker
|
||||
w.Write(i);
|
||||
}
|
||||
else {
|
||||
throw new Exception($"Unsupported constant type: {c.GetType()}");
|
||||
}
|
||||
}
|
||||
|
||||
// Variablen
|
||||
w.Write((ushort)syms.Count);
|
||||
var types = new byte[syms.Count];
|
||||
foreach(var kv in syms)
|
||||
types[kv.Value.Index] = (byte)kv.Value.Type;
|
||||
foreach(var b in types)
|
||||
w.Write(b);
|
||||
|
||||
// Code
|
||||
w.Write((ushort)code.Count);
|
||||
w.Write(code.ToArray());
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
14
STCompiler.Compiler/STCompiler.Compiler.csproj
Normal file
14
STCompiler.Compiler/STCompiler.Compiler.csproj
Normal file
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\STCompiler.Common\STCompiler.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Common.dll
Normal file
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Common.dll
Normal file
Binary file not shown.
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Common.pdb
Normal file
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Common.pdb
Normal file
Binary file not shown.
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler
Executable file
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler
Executable file
Binary file not shown.
@ -0,0 +1,36 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v8.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"STCompiler.Compiler/1.0.0": {
|
||||
"dependencies": {
|
||||
"STCompiler.Common": "1.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"STCompiler.Compiler.dll": {}
|
||||
}
|
||||
},
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"runtime": {
|
||||
"STCompiler.Common.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"STCompiler.Compiler/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler.dll
Normal file
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler.dll
Normal file
Binary file not shown.
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler.pdb
Normal file
BIN
STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler.pdb
Normal file
Binary file not shown.
@ -0,0 +1,12 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net8.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "8.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||
}
|
||||
}
|
||||
}
|
||||
16
STCompiler.Compiler/input.st
Normal file
16
STCompiler.Compiler/input.st
Normal file
@ -0,0 +1,16 @@
|
||||
PROGRAM Demo
|
||||
VAR
|
||||
a UINT := 0;
|
||||
b UINT := 0;
|
||||
i UINT := 0;
|
||||
END_VAR
|
||||
|
||||
WHILE a < 5 DO
|
||||
a := a + 1;
|
||||
END_WHILE;
|
||||
|
||||
FOR i := 1 TO 10 DO
|
||||
b := b + i;
|
||||
END_FOR;
|
||||
|
||||
END_PROGRAM
|
||||
@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("STCompiler.Compiler")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("STCompiler.Compiler")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("STCompiler.Compiler")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@ -0,0 +1 @@
|
||||
62e0a705d77d04812d8911688545c821288c02824251ca71c994335e8a831b77
|
||||
@ -0,0 +1,13 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net8.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = STCompiler.Compiler
|
||||
build_property.ProjectDir = /home/martin/Projects/STCompiler/STCompiler.Compiler/
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
@ -0,0 +1,8 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
721350078d8e27a83d96cc6d0dfa91b6ac559a5f81a22d9c78bae64825ed0c98
|
||||
@ -0,0 +1,18 @@
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler.deps.json
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler.runtimeconfig.json
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Compiler.pdb
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Common.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/bin/Debug/net8.0/STCompiler.Common.pdb
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.csproj.AssemblyReference.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.GeneratedMSBuildEditorConfig.editorconfig
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.AssemblyInfoInputs.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.AssemblyInfo.cs
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.csproj.CoreCompileInputs.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.csproj.CopyComplete
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/refint/STCompiler.Compiler.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.pdb
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.genruntimeconfig.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/Debug/net8.0/ref/STCompiler.Compiler.dll
|
||||
BIN
STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.dll
Normal file
BIN
STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.dll
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
||||
a4bc37825fdc00aadca1794cf7a7ec833f4b0bab9ce25c074c60fc7b293e6157
|
||||
BIN
STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.pdb
Normal file
BIN
STCompiler.Compiler/obj/Debug/net8.0/STCompiler.Compiler.pdb
Normal file
Binary file not shown.
BIN
STCompiler.Compiler/obj/Debug/net8.0/apphost
Executable file
BIN
STCompiler.Compiler/obj/Debug/net8.0/apphost
Executable file
Binary file not shown.
BIN
STCompiler.Compiler/obj/Debug/net8.0/ref/STCompiler.Compiler.dll
Normal file
BIN
STCompiler.Compiler/obj/Debug/net8.0/ref/STCompiler.Compiler.dll
Normal file
Binary file not shown.
Binary file not shown.
@ -0,0 +1,130 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Compiler/STCompiler.Compiler.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"projectName": "STCompiler.Common",
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"packagesPath": "/home/martin/.nuget/packages/",
|
||||
"outputPath": "/home/martin/Projects/STCompiler/STCompiler.Common/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/martin/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.20, 8.0.20]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/8.0.120/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Compiler/STCompiler.Compiler.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/martin/Projects/STCompiler/STCompiler.Compiler/STCompiler.Compiler.csproj",
|
||||
"projectName": "STCompiler.Compiler",
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Compiler/STCompiler.Compiler.csproj",
|
||||
"packagesPath": "/home/martin/.nuget/packages/",
|
||||
"outputPath": "/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/martin/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj": {
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.20, 8.0.20]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/8.0.120/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/martin/.nuget/packages/</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/martin/.nuget/packages/</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.8.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="/home/martin/.nuget/packages/" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
95
STCompiler.Compiler/obj/project.assets.json
Normal file
95
STCompiler.Compiler/obj/project.assets.json
Normal file
@ -0,0 +1,95 @@
|
||||
{
|
||||
"version": 3,
|
||||
"targets": {
|
||||
"net8.0": {
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"type": "project",
|
||||
"framework": ".NETCoreApp,Version=v8.0",
|
||||
"compile": {
|
||||
"bin/placeholder/STCompiler.Common.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"bin/placeholder/STCompiler.Common.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"type": "project",
|
||||
"path": "../STCompiler.Common/STCompiler.Common.csproj",
|
||||
"msbuildProject": "../STCompiler.Common/STCompiler.Common.csproj"
|
||||
}
|
||||
},
|
||||
"projectFileDependencyGroups": {
|
||||
"net8.0": [
|
||||
"STCompiler.Common >= 1.0.0"
|
||||
]
|
||||
},
|
||||
"packageFolders": {
|
||||
"/home/martin/.nuget/packages/": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/martin/Projects/STCompiler/STCompiler.Compiler/STCompiler.Compiler.csproj",
|
||||
"projectName": "STCompiler.Compiler",
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Compiler/STCompiler.Compiler.csproj",
|
||||
"packagesPath": "/home/martin/.nuget/packages/",
|
||||
"outputPath": "/home/martin/Projects/STCompiler/STCompiler.Compiler/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/martin/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj": {
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.20, 8.0.20]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/8.0.120/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
STCompiler.Compiler/obj/project.nuget.cache
Normal file
10
STCompiler.Compiler/obj/project.nuget.cache
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "pOc/XBic+bS/nY5zfA5/C00qF5czDCXpa+QmG0s/xXRdiSa+OYPNVVz01R8yAbKlACRDVmGtIdQwJXDTjGwwYg==",
|
||||
"success": true,
|
||||
"projectFilePath": "/home/martin/Projects/STCompiler/STCompiler.Compiler/STCompiler.Compiler.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"/home/martin/.nuget/packages/microsoft.aspnetcore.app.ref/8.0.20/microsoft.aspnetcore.app.ref.8.0.20.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
BIN
STCompiler.Compiler/output.bin
Normal file
BIN
STCompiler.Compiler/output.bin
Normal file
Binary file not shown.
76
STCompiler.Disassembler/Program.cs
Normal file
76
STCompiler.Disassembler/Program.cs
Normal file
@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using STCompiler.Common;
|
||||
using System.Collections.Generic;
|
||||
|
||||
class Program {
|
||||
static int Main(string[] args) {
|
||||
if (args.Length < 1) {
|
||||
Console.WriteLine("Usage: StDisasm <file.stbc>");
|
||||
return 1;
|
||||
}
|
||||
var path = args[0];
|
||||
if (!File.Exists(path)) { Console.WriteLine("File not found: " + path); return 2; }
|
||||
var data = File.ReadAllBytes(path);
|
||||
try { Disasm(data); } catch(Exception ex) { Console.WriteLine("Error: " + ex.Message); return 3; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Disasm(byte[] data) {
|
||||
using var ms = new MemoryStream(data);
|
||||
using var r = new BinaryReader(ms);
|
||||
|
||||
string magic = Encoding.ASCII.GetString(r.ReadBytes(4));
|
||||
Console.WriteLine($"Magic: {magic}");
|
||||
ushort ver = r.ReadUInt16();
|
||||
Console.WriteLine($"Version: {ver}");
|
||||
ushort nConsts = r.ReadUInt16();
|
||||
Console.WriteLine($"Consts: {nConsts}");
|
||||
var consts = new List<object>();
|
||||
for (int i = 0; i < nConsts; i++) {
|
||||
byte t = r.ReadByte();
|
||||
switch(t) {
|
||||
case 1: { long v = r.ReadInt64(); consts.Add(v); Console.WriteLine($" [{i}] (long) = {v}"); break; }
|
||||
case 2: { double v = r.ReadDouble(); consts.Add(v); Console.WriteLine($" [{i}] (double) = {v}"); break; }
|
||||
case 3: { float v = r.ReadSingle(); consts.Add(v); Console.WriteLine($" [{i}] (float) = {v}"); break; }
|
||||
case 4: { int v = r.ReadInt32(); consts.Add(v); Console.WriteLine($" [{i}] (int) = {v}"); break; }
|
||||
default: { Console.WriteLine($" [{i}] Unknown const type {t}"); break; }
|
||||
}
|
||||
}
|
||||
|
||||
ushort nVars = r.ReadUInt16();
|
||||
Console.WriteLine($"Vars: {nVars}");
|
||||
var varTypes = new byte[nVars];
|
||||
for (int i = 0; i < nVars; i++) { varTypes[i] = r.ReadByte(); Console.WriteLine($" Var[{i}] type = {varTypes[i]}"); }
|
||||
|
||||
ushort codeLen = r.ReadUInt16();
|
||||
Console.WriteLine($"CodeLen: {codeLen} bytes");
|
||||
var code = r.ReadBytes(codeLen);
|
||||
|
||||
Console.WriteLine("\n--- Disassembly ---");
|
||||
int ip = 0;
|
||||
while (ip < code.Length) {
|
||||
int addr = ip;
|
||||
byte op = code[ip++];
|
||||
Console.Write($"{addr:0000}: 0x{op:X2} {Bytecode.OpName(op)} ");
|
||||
switch (op) {
|
||||
case Bytecode.OpCodes.NOP: Console.WriteLine("NOP"); break;
|
||||
case Bytecode.OpCodes.PUSH_CONST: { ushort ci = ReadU16(code, ref ip); Console.WriteLine($"PUSH_CONST {ci} ({consts[ci]})"); break; }
|
||||
case Bytecode.OpCodes.PUSH_REAL_CONST: { ushort ci = ReadU16(code, ref ip); Console.WriteLine($"PUSH_REAL_CONST {ci} ({consts[ci]})"); break; }
|
||||
case Bytecode.OpCodes.LOAD_VAR: { ushort vi = ReadU16(code, ref ip); Console.WriteLine($"LOAD_VAR {vi}"); break; }
|
||||
case Bytecode.OpCodes.STORE_VAR: { ushort vi = ReadU16(code, ref ip); Console.WriteLine($"STORE_VAR {vi}"); break; }
|
||||
case Bytecode.OpCodes.JZ: { ushort target = ReadU16(code, ref ip); Console.WriteLine($"JZ addr={target}"); break; }
|
||||
case Bytecode.OpCodes.JMP: { ushort target = ReadU16(code, ref ip); Console.WriteLine($"JMP addr={target}"); break; }
|
||||
case Bytecode.OpCodes.HALT: Console.WriteLine("HALT"); break;
|
||||
default: Console.WriteLine($"{Bytecode.OpName(op)}"); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ushort ReadU16(byte[] a, ref int ip) {
|
||||
ushort v = (ushort)(a[ip] | (a[ip+1] << 8));
|
||||
ip += 2;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
14
STCompiler.Disassembler/STCompiler.Disassembler.csproj
Normal file
14
STCompiler.Disassembler/STCompiler.Disassembler.csproj
Normal file
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\STCompiler.Common\STCompiler.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
BIN
STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Common.dll
Normal file
BIN
STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Common.dll
Normal file
Binary file not shown.
BIN
STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Common.pdb
Normal file
BIN
STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Common.pdb
Normal file
Binary file not shown.
BIN
STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Disassembler
Executable file
BIN
STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Disassembler
Executable file
Binary file not shown.
@ -0,0 +1,36 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v8.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"STCompiler.Disassembler/1.0.0": {
|
||||
"dependencies": {
|
||||
"STCompiler.Common": "1.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"STCompiler.Disassembler.dll": {}
|
||||
}
|
||||
},
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"runtime": {
|
||||
"STCompiler.Common.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"STCompiler.Disassembler/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,12 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net8.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "8.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("STCompiler.Disassembler")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("STCompiler.Disassembler")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("STCompiler.Disassembler")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@ -0,0 +1 @@
|
||||
dc637a389172b7c1d98556c8fdb0f7e6b7d0182cadc40b75d2a802cc3145ba46
|
||||
@ -0,0 +1,13 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net8.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = STCompiler.Disassembler
|
||||
build_property.ProjectDir = /home/martin/Projects/STCompiler/STCompiler.Disassembler/
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
@ -0,0 +1,8 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
fed524f70924a7a6242fb1ec88f1925ce6879f83c899f8ed3dffe3ffd15c88b0
|
||||
@ -0,0 +1,18 @@
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Disassembler
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Disassembler.deps.json
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Disassembler.runtimeconfig.json
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Disassembler.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Disassembler.pdb
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Common.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/bin/Debug/net8.0/STCompiler.Common.pdb
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.csproj.AssemblyReference.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.GeneratedMSBuildEditorConfig.editorconfig
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.AssemblyInfoInputs.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.AssemblyInfo.cs
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.csproj.CoreCompileInputs.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.csproj.CopyComplete
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/refint/STCompiler.Disassembler.dll
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.pdb
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/STCompiler.Disassembler.genruntimeconfig.cache
|
||||
/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/Debug/net8.0/ref/STCompiler.Disassembler.dll
|
||||
Binary file not shown.
@ -0,0 +1 @@
|
||||
0f919aa6f48480752187acc6336f3dd954d81be64b7f977f5e7455370c6b0417
|
||||
Binary file not shown.
BIN
STCompiler.Disassembler/obj/Debug/net8.0/apphost
Executable file
BIN
STCompiler.Disassembler/obj/Debug/net8.0/apphost
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,130 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Disassembler/STCompiler.Disassembler.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"projectName": "STCompiler.Common",
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj",
|
||||
"packagesPath": "/home/martin/.nuget/packages/",
|
||||
"outputPath": "/home/martin/Projects/STCompiler/STCompiler.Common/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/martin/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.20, 8.0.20]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/8.0.120/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Disassembler/STCompiler.Disassembler.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/martin/Projects/STCompiler/STCompiler.Disassembler/STCompiler.Disassembler.csproj",
|
||||
"projectName": "STCompiler.Disassembler",
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Disassembler/STCompiler.Disassembler.csproj",
|
||||
"packagesPath": "/home/martin/.nuget/packages/",
|
||||
"outputPath": "/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/martin/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj": {
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.20, 8.0.20]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/8.0.120/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/martin/.nuget/packages/</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/martin/.nuget/packages/</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.8.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="/home/martin/.nuget/packages/" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
95
STCompiler.Disassembler/obj/project.assets.json
Normal file
95
STCompiler.Disassembler/obj/project.assets.json
Normal file
@ -0,0 +1,95 @@
|
||||
{
|
||||
"version": 3,
|
||||
"targets": {
|
||||
"net8.0": {
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"type": "project",
|
||||
"framework": ".NETCoreApp,Version=v8.0",
|
||||
"compile": {
|
||||
"bin/placeholder/STCompiler.Common.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"bin/placeholder/STCompiler.Common.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"type": "project",
|
||||
"path": "../STCompiler.Common/STCompiler.Common.csproj",
|
||||
"msbuildProject": "../STCompiler.Common/STCompiler.Common.csproj"
|
||||
}
|
||||
},
|
||||
"projectFileDependencyGroups": {
|
||||
"net8.0": [
|
||||
"STCompiler.Common >= 1.0.0"
|
||||
]
|
||||
},
|
||||
"packageFolders": {
|
||||
"/home/martin/.nuget/packages/": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/martin/Projects/STCompiler/STCompiler.Disassembler/STCompiler.Disassembler.csproj",
|
||||
"projectName": "STCompiler.Disassembler",
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Disassembler/STCompiler.Disassembler.csproj",
|
||||
"packagesPath": "/home/martin/.nuget/packages/",
|
||||
"outputPath": "/home/martin/Projects/STCompiler/STCompiler.Disassembler/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/martin/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {
|
||||
"/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj": {
|
||||
"projectPath": "/home/martin/Projects/STCompiler/STCompiler.Common/STCompiler.Common.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.20, 8.0.20]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/8.0.120/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
STCompiler.Disassembler/obj/project.nuget.cache
Normal file
10
STCompiler.Disassembler/obj/project.nuget.cache
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "s0tj8ngaSHf4PEU0x7K1E9bEHGayTmYwySGUMOEav8+YNokCEe1HNBdMoO+cEMLuxPCm3+TQcBxCGTSvXq6UBQ==",
|
||||
"success": true,
|
||||
"projectFilePath": "/home/martin/Projects/STCompiler/STCompiler.Disassembler/STCompiler.Disassembler.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"/home/martin/.nuget/packages/microsoft.aspnetcore.app.ref/8.0.20/microsoft.aspnetcore.app.ref.8.0.20.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
123
STCompiler.Simulator/Program.cs
Normal file
123
STCompiler.Simulator/Program.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using STCompiler.Common;
|
||||
using System.Collections.Generic;
|
||||
|
||||
class Program {
|
||||
static int Main(string[] args) {
|
||||
if (args.Length < 1) {
|
||||
Console.WriteLine("Usage: StSim <file.stbc>");
|
||||
return 1;
|
||||
}
|
||||
var path = args[0];
|
||||
if (!File.Exists(path)) { Console.WriteLine("File not found: " + path); return 2; }
|
||||
var data = File.ReadAllBytes(path);
|
||||
try { Simulate(data); } catch(Exception ex) { Console.WriteLine("Error: " + ex.Message); return 3; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Simulate(byte[] data) {
|
||||
using var ms = new MemoryStream(data);
|
||||
using var r = new BinaryReader(ms);
|
||||
|
||||
string magic = System.Text.Encoding.ASCII.GetString(r.ReadBytes(4));
|
||||
if (magic != Bytecode.Magic) throw new Exception("Invalid magic");
|
||||
ushort ver = r.ReadUInt16();
|
||||
if (ver != Bytecode.Version) throw new Exception($"Unsupported version {ver}");
|
||||
|
||||
ushort nConsts = r.ReadUInt16();
|
||||
var consts = new List<object>();
|
||||
for (int i = 0; i < nConsts; i++) {
|
||||
byte t = r.ReadByte();
|
||||
switch(t) {
|
||||
case 1: consts.Add(r.ReadInt64()); break;
|
||||
case 2: consts.Add(r.ReadDouble()); break;
|
||||
case 3: consts.Add(r.ReadSingle()); break;
|
||||
case 4: consts.Add(r.ReadInt32()); break;
|
||||
default: throw new Exception($"Unknown const type {t}");
|
||||
}
|
||||
}
|
||||
|
||||
ushort nVars = r.ReadUInt16();
|
||||
var varTypes = new VarType[nVars];
|
||||
for (int i = 0; i < nVars; i++) varTypes[i] = (VarType)r.ReadByte();
|
||||
|
||||
ushort codeLen = r.ReadUInt16();
|
||||
var code = r.ReadBytes(codeLen);
|
||||
|
||||
var stack = new Stack<object>();
|
||||
var vars = new object[nVars];
|
||||
int ip = 0;
|
||||
while (ip < code.Length) {
|
||||
byte op = code[ip++];
|
||||
switch(op) {
|
||||
case Bytecode.OpCodes.NOP: break;
|
||||
case Bytecode.OpCodes.PUSH_CONST: {
|
||||
ushort ci = (ushort)(code[ip++] | (code[ip++] << 8));
|
||||
stack.Push(consts[ci]);
|
||||
break;
|
||||
}
|
||||
case Bytecode.OpCodes.PUSH_REAL_CONST: {
|
||||
ushort ci = (ushort)(code[ip++] | (code[ip++] << 8));
|
||||
stack.Push(consts[ci]);
|
||||
break;
|
||||
}
|
||||
case Bytecode.OpCodes.LOAD_VAR: {
|
||||
ushort vi = (ushort)(code[ip++] | (code[ip++] << 8));
|
||||
stack.Push(vars[vi]);
|
||||
break;
|
||||
}
|
||||
case Bytecode.OpCodes.STORE_VAR: {
|
||||
ushort vi = (ushort)(code[ip++] | (code[ip++] << 8));
|
||||
vars[vi] = stack.Pop();
|
||||
break;
|
||||
}
|
||||
case Bytecode.OpCodes.JZ: {
|
||||
ushort target = (ushort)(code[ip++] | (code[ip++] << 8));
|
||||
var cond = stack.Pop();
|
||||
bool isFalse = cond is int ci ? ci == 0 : cond is long cl ? cl == 0L : cond is double cd ? cd == 0.0 : cond == null;
|
||||
if (isFalse) ip = target;
|
||||
break;
|
||||
}
|
||||
case Bytecode.OpCodes.JMP: {
|
||||
ushort target = (ushort)(code[ip++] | (code[ip++] << 8));
|
||||
ip = target;
|
||||
break;
|
||||
}
|
||||
case Bytecode.OpCodes.HALT:
|
||||
Console.WriteLine("HALT");
|
||||
return;
|
||||
default:
|
||||
// Simple arithmetic handlers for some opcodes
|
||||
if (Bytecode.OpName(op).StartsWith("ADD_")) {
|
||||
dynamic b = stack.Pop(); dynamic a = stack.Pop(); stack.Push(a + b); break;
|
||||
}
|
||||
if (Bytecode.OpName(op).StartsWith("SUB_")) {
|
||||
dynamic b = stack.Pop(); dynamic a = stack.Pop(); stack.Push(a - b); break;
|
||||
}
|
||||
if (Bytecode.OpName(op).StartsWith("MUL_")) {
|
||||
dynamic b = stack.Pop(); dynamic a = stack.Pop(); stack.Push(a * b); break;
|
||||
}
|
||||
if (Bytecode.OpName(op).StartsWith("DIV_")) {
|
||||
dynamic b = stack.Pop(); dynamic a = stack.Pop(); stack.Push(a / b); break;
|
||||
}
|
||||
if (Bytecode.OpName(op).StartsWith("LT_") || Bytecode.OpName(op).StartsWith("GT_") || Bytecode.OpName(op).StartsWith("LE_") || Bytecode.OpName(op).StartsWith("GE_") || Bytecode.OpName(op).StartsWith("EQ_") || Bytecode.OpName(op).StartsWith("NEQ_")) {
|
||||
// comparisons: pop r, pop l, push int 0/1
|
||||
dynamic rVal = stack.Pop(); dynamic lVal = stack.Pop();
|
||||
bool res = Bytecode.OpName(op).StartsWith("LT_") ? (lVal < rVal) :
|
||||
Bytecode.OpName(op).StartsWith("GT_") ? (lVal > rVal) :
|
||||
Bytecode.OpName(op).StartsWith("LE_") ? (lVal <= rVal) :
|
||||
Bytecode.OpName(op).StartsWith("GE_") ? (lVal >= rVal) :
|
||||
Bytecode.OpName(op).StartsWith("EQ_") ? (lVal == rVal) :
|
||||
(lVal != rVal);
|
||||
stack.Push(res ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
throw new Exception($"Unknown opcode 0x{op:X2}");
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("Execution finished");
|
||||
for (int i = 0; i < vars.Length; i++) Console.WriteLine($"Var[{i}] = {vars[i]}");
|
||||
}
|
||||
}
|
||||
11
STCompiler.Simulator/STCompiler.Simulator.csproj
Normal file
11
STCompiler.Simulator/STCompiler.Simulator.csproj
Normal file
@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\STCompiler.Common\STCompiler.Common.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Common.dll
Normal file
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Common.dll
Normal file
Binary file not shown.
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Common.pdb
Normal file
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Common.pdb
Normal file
Binary file not shown.
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Simulator
Executable file
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Simulator
Executable file
Binary file not shown.
@ -0,0 +1,36 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v8.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"STCompiler.Simulator/1.0.0": {
|
||||
"dependencies": {
|
||||
"STCompiler.Common": "1.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"STCompiler.Simulator.dll": {}
|
||||
}
|
||||
},
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"runtime": {
|
||||
"STCompiler.Common.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"STCompiler.Simulator/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"STCompiler.Common/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Simulator.dll
Normal file
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Simulator.dll
Normal file
Binary file not shown.
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Simulator.pdb
Normal file
BIN
STCompiler.Simulator/bin/Debug/net8.0/STCompiler.Simulator.pdb
Normal file
Binary file not shown.
@ -0,0 +1,12 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net8.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "8.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("STCompiler.Simulator")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("STCompiler.Simulator")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("STCompiler.Simulator")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user