ソースを参照

Added a calculator memory

master
Ludovic 'Archivist' Lagouardette 3年前
コミット
d61677c680
5個のファイルの変更128行の追加21行の削除
  1. +35
    -7
      BasicNumber.cs
  2. +56
    -0
      Functions/Memory.cs
  3. +30
    -14
      Parser.cs
  4. +2
    -0
      Program.cs
  5. +5
    -0
      Test.basic

+ 35
- 7
BasicNumber.cs ファイルの表示

@ -7,7 +7,8 @@ namespace SuperBASIC
enum NumberType{
Ans,
Number,
Operand
Operand,
Memory
};
struct BasicNumber
@ -18,6 +19,18 @@ namespace SuperBASIC
readonly private float number;
readonly private int operand;
[Serializable]
public class BadNumber : Exception
{
public BadNumber() { }
public BadNumber(string message) : base(message) { }
public BadNumber(string message, Exception inner) : base(message, inner) { }
protected BadNumber(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
internal BasicNumber(Runtime rt, float v)
{
type = NumberType.Number;
@ -32,12 +45,23 @@ namespace SuperBASIC
operand = 0;
runtime = rt;
}
internal BasicNumber(Runtime rt, int v)
internal BasicNumber(Runtime rt, int v, NumberType reqType = NumberType.Operand)
{
type = NumberType.Operand;
number = 0;
operand = v;
runtime = rt;
if(reqType == NumberType.Operand)
{
type = NumberType.Operand;
number = 0;
operand = v;
runtime = rt;
}
else
{
type = NumberType.Memory;
number = 0;
if (v > Int16.MaxValue) throw new BadNumber("Generated out of memory access");
operand = v;
runtime = rt;
}
}
internal int GetOperand()
@ -51,10 +75,14 @@ namespace SuperBASIC
{
return number;
}
else
else if(type == NumberType.Ans)
{
return runtime.GetRegister();
}
else
{
return Functions.Memory.MemoryGet((short)operand);
}
}
public static implicit operator float(BasicNumber v) => v.GetValue();

+ 56
- 0
Functions/Memory.cs ファイルの表示

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SuperBASIC.Functions
{
static class Memory
{
internal static float[] memory = new float[Int16.MaxValue];
internal static float MemoryGet(Int16 pos) => memory[pos];
internal static float MemorySet(Int16 pos, float value)
{
memory[pos] = value;
return value;
}
[Serializable]
public class BadMemoryAccess : Exception
{
public BadMemoryAccess() { }
public BadMemoryAccess(string message) : base(message) { }
public BadMemoryAccess(string message, Exception inner) : base(message, inner) { }
protected BadMemoryAccess(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}
class MemoryLoad : IFunction
{
float IFunction.Apply(List<BasicNumber> arguments)
{
float value = arguments[0].GetValue();
if(value == (int)value && value >= 0 && value < Int16.MaxValue)
{
return Memory.MemoryGet((short)value);
}
throw new Memory.BadMemoryAccess("Could not access requested memory");
}
}
class MemoryStore : IFunction
{
float IFunction.Apply(List<BasicNumber> arguments)
{
float value = arguments[0].GetValue();
if (value == (int)value && value >= 0 && value < Int16.MaxValue)
{
return Memory.MemorySet((short)value, arguments[1]);
}
throw new Memory.BadMemoryAccess("Could not access requested memory");
}
}
}

+ 30
- 14
Parser.cs ファイルの表示

@ -46,7 +46,7 @@ namespace SuperBASIC
l = leadings.Replace(l, "");
l = trailings.Replace(l, "");
if(l != String.Empty)
if (l != String.Empty)
{
lineSpans.Add(a);
a = 0;
@ -54,48 +54,64 @@ namespace SuperBASIC
}
}
for(int idx = 0; idx < codeLines.Count; idx++)
for (int idx = 0; idx < codeLines.Count; idx++)
{
string line = codeLines[idx];
var components = line.Split(' ');
if(!library.nameResolution.ContainsKey(components[0]))
if (!library.nameResolution.ContainsKey(components[0]))
{
int lineIndex = 0;
foreach (int cnt in lineSpans.GetRange(0, idx+1)) lineIndex += cnt;
foreach (int cnt in lineSpans.GetRange(0, idx + 1)) lineIndex += cnt;
throw new ParseException($"Unknown operation \"{components[0]}\"\n\tat line {lineIndex}");
}
int opcode = library.nameResolution[components[0]];
int arity = library.arities[opcode];
if(arity != components.Length-1)
if (arity != components.Length - 1)
{
int lineIndex = 0;
foreach (int cnt in lineSpans.GetRange(0, idx+1)) lineIndex += cnt;
throw new ParseException($"Operation {components[0]} was provided with the wrong number of arguments\n\tExpected {arity} found {components.Length-1}\n\tat line {lineIndex}");
foreach (int cnt in lineSpans.GetRange(0, idx + 1)) lineIndex += cnt;
throw new ParseException($"Operation {components[0]} was provided with the wrong number of arguments\n\tExpected {arity} found {components.Length - 1}\n\tat line {lineIndex}");
}
c.bytecode.Add(new BasicNumber(runtime, opcode));
foreach (string elem in components.AsSpan(1))
{
if (elem != "$")
if (elem.StartsWith("M"))
{
try
{
kt">float v = float.Parse(elem);
c.bytecode.Add(new BasicNumber(runtime, v));
n">Int16 v = Int16.Parse(elem[1..]);
c.bytecode.Add(new BasicNumber(runtime, v, NumberType.Memory));
}
catch(Exception) {
catch (Exception)
{
int lineIndex = 0;
foreach (int cnt in lineSpans.GetRange(0, idx+1)) lineIndex += cnt;
throw new ParseException($"Cannot parse {elem} as argument\n\tExpected floating point number or '$'\n\tat line {lineIndex}");
foreach (int cnt in lineSpans.GetRange(0, idx + 1)) lineIndex += cnt;
throw new ParseException($"Cannot parse {elem} as argument to memory address\n\tExpected 'M' followed by an integer lower than {Int16.MaxValue}\n\tat line {lineIndex}");
}
}
else
else if (elem == "$")
{
c.bytecode.Add(new BasicNumber(runtime));
}
else
{
try
{
float v = float.Parse(elem);
c.bytecode.Add(new BasicNumber(runtime, v));
}
catch (Exception)
{
int lineIndex = 0;
foreach (int cnt in lineSpans.GetRange(0, idx + 1)) lineIndex += cnt;
throw new ParseException($"Cannot parse {elem} as argument\n\tExpected floating point number or '$' or memory argument\n\tat line {lineIndex}");
}
}
}
}

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

@ -10,6 +10,8 @@ namespace SuperBASIC
try
{
Library lib = new Library();
lib.AddFunction(new Functions.MemoryLoad(), 1, "MEMLOAD");
lib.AddFunction(new Functions.MemoryStore(), 2, "MEMSTORE");
lib.AddFunction(new Functions.Print(), 1, "PRINT");
lib.AddFunction(new Functions.Multiply(), 2, "MULTIPLY");
lib.AddFunction(new Functions.Compare(), 2, "COMPARE");

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

@ -1,4 +1,9 @@
EULER
MULTIPLY $ $
MEMSTORE 0 $
COMPARE $ 7.3890557
PRINT $
MULTIPLY 2 3
PRINT $
MEMLOAD 0
PRINT $

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