ソースを参照

Add project files.

master
Ludovic 'Archivist' Lagouardette 3年前
コミット
40ef31c1e0
12個のファイルの変更335行の追加0行の削除
  1. +60
    -0
      BasicNumber.cs
  2. +16
    -0
      Bytecode.cs
  3. +14
    -0
      Functions/Multiply.cs
  4. +15
    -0
      Functions/Print.cs
  5. +11
    -0
      IFunction.cs
  6. +29
    -0
      Library.cs
  7. +86
    -0
      Parser.cs
  8. +18
    -0
      Program.cs
  9. +45
    -0
      Runtime.cs
  10. +14
    -0
      SuperBASIC.csproj
  11. +25
    -0
      SuperBASIC.sln
  12. +2
    -0
      Test.basic

+ 60
- 0
BasicNumber.cs ファイルの表示

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SuperBASIC
{
enum NumberType{
Ans,
Number,
Operand
};
struct BasicNumber
{
internal NumberType type;
readonly Runtime runtime;
readonly private float number;
readonly private int operand;
internal BasicNumber(Runtime rt, float v)
{
type = NumberType.Number;
number = v;
operand = 0;
runtime = rt;
}
internal BasicNumber(Runtime rt)
{
type = NumberType.Ans;
number = 0;
operand = 0;
runtime = rt;
}
internal BasicNumber(Runtime rt, int v)
{
type = NumberType.Operand;
number = 0;
operand = v;
runtime = rt;
}
internal int GetOperand()
{
return operand;
}
public float GetValue()
{
if (type == NumberType.Number)
{
return number;
}
else
{
return runtime.GetRegister();
}
}
}
}

+ 16
- 0
Bytecode.cs ファイルの表示

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SuperBASIC
{
class Bytecode
{
internal List<BasicNumber> bytecode;
internal Bytecode()
{
bytecode = new List<BasicNumber>();
}
}
}

+ 14
- 0
Functions/Multiply.cs ファイルの表示

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SuperBASIC.Functions
{
class Multiply : IFunction
{
float IFunction.Apply(List<BasicNumber> arguments)
{
return arguments[0].GetValue() * arguments[1].GetValue();
}
}
}

+ 15
- 0
Functions/Print.cs ファイルの表示

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SuperBASIC.Functions
{
class Print : IFunction
{
float IFunction.Apply(List<BasicNumber> arguments)
{
Console.WriteLine(arguments[0].GetValue());
return 0f;
}
}
}

+ 11
- 0
IFunction.cs ファイルの表示

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SuperBASIC
{
interface IFunction
{
public float Apply(List<BasicNumber> arguments);
}
}

+ 29
- 0
Library.cs ファイルの表示

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SuperBASIC
{
class Library
{
internal List<IFunction> functions;
internal List<int> arities;
internal Dictionary<string, int> nameResolution;
public Library()
{
functions = new List<IFunction>();
arities = new List<int>();
nameResolution = new Dictionary<string, int>();
}
public int AddFunction(IFunction fn, int arity, string name)
{
int idx = functions.Count;
functions.Add(fn);
arities.Add(arity);
nameResolution[name] = idx;
return idx;
}
}
}

+ 86
- 0
Parser.cs ファイルの表示

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace SuperBASIC
{
class Parser
{
[Serializable]
public class ParseException : Exception
{
public ParseException() { }
public ParseException(string message) : base(message) { }
public ParseException(string message, Exception inner) : base(message, inner) { }
protected ParseException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
readonly Library library;
readonly Runtime runtime;
public Parser(Runtime rt)
{
runtime = rt;
library = rt.lib;
}
public Bytecode ParseFile(string filepath)
{
Bytecode c = new Bytecode();
string[] sourceLines = File.ReadAllLines(filepath);
Regex lws = new Regex(@"\s+");
Regex leadings = new Regex(@"^\s+");
Regex trailings = new Regex(@"\s+$");
List<string> codeLines = new List<string>();
foreach (string line in sourceLines)
{
string l = lws.Replace(line, " ");
l = leadings.Replace(l, "");
l = trailings.Replace(l, "");
if(l != String.Empty)
{
codeLines.Add(l);
}
}
foreach(string line in codeLines)
{
var components = line.Split(' ');
if(!library.nameResolution.ContainsKey(components[0]))
{
throw new ParseException("Unknown operation \"" + components[0] + "\"");
}
int opcode = library.nameResolution[components[0]];
int arity = library.arities[opcode];
if(arity != components.Length-1)
{
throw new ParseException("Operation " + components[0] + " was provided with the wrong number of arguments: Expected "+arity.ToString()+" found "+(components.Length-1).ToString());
}
c.bytecode.Add(new BasicNumber(runtime, opcode));
foreach (string elem in components.AsSpan(1))
{
if (elem != "$")
{
c.bytecode.Add(new BasicNumber(runtime, float.Parse(elem)));
}
else
{
c.bytecode.Add(new BasicNumber(runtime));
}
}
}
return c;
}
}
}

+ 18
- 0
Program.cs ファイルの表示

@ -0,0 +1,18 @@
using System;
using System.IO;
namespace SuperBASIC
{
class Program
{
static void Main(string[] args)
{
Library lib = new Library();
lib.AddFunction(new Functions.Print(), 1, "PRINT");
lib.AddFunction(new Functions.Multiply(), 2, "MULTIPLY");
Runtime r = new Runtime(lib);
r.OpenFile(Directory.GetCurrentDirectory() + "\\Test.basic");
r.Run();
}
}
}

+ 45
- 0
Runtime.cs ファイルの表示

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SuperBASIC
{
class Runtime
{
float register;
internal Library lib;
Bytecode code;
public Runtime(Library library)
{
lib = library;
}
public void OpenFile(string path)
{
code = new Parser(this).ParseFile(path);
}
public void Run()
{
for(int idx = 0; idx < code.bytecode.Count;)
{
int opcode = code.bytecode[idx].GetOperand();
int arity = lib.arities[opcode];
IFunction op = lib.functions[opcode];
var args = code.bytecode.GetRange(idx + 1, arity);
SetRegister(op.Apply(args));
idx += arity + 1;
}
}
internal void SetRegister(float value)
{
register = value;
}
internal float GetRegister()
{
return register;
}
}
}

+ 14
- 0
SuperBASIC.csproj ファイルの表示

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Update="Test.basic">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

+ 25
- 0
SuperBASIC.sln ファイルの表示

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30907.101
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SuperBASIC", "SuperBASIC.csproj", "{51942D92-4C96-4FD9-AA5B-C35661E3B063}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{51942D92-4C96-4FD9-AA5B-C35661E3B063}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51942D92-4C96-4FD9-AA5B-C35661E3B063}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51942D92-4C96-4FD9-AA5B-C35661E3B063}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51942D92-4C96-4FD9-AA5B-C35661E3B063}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B03097C8-5C88-49D7-BD8F-EF905E9827EA}
EndGlobalSection
EndGlobal

+ 2
- 0
Test.basic ファイルの表示

@ -0,0 +1,2 @@
MULTIPLY 2 3
PRINT $

読み込み中…
キャンセル
保存