Compare commits
3 Commits
feature/TR
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f3c4a1b537 | |||
| 4d7d246431 | |||
| 727600a19d |
@@ -8,7 +8,7 @@
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Axiom.Core</RootNamespace>
|
||||
<AssemblyName>Axiom.Core</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
@@ -64,6 +64,7 @@
|
||||
<Compile Include="Interpreter\Assembler.cs" />
|
||||
<Compile Include="Interpreter\AxiomException.cs" />
|
||||
<Compile Include="Interpreter\AxiomTrace.cs" />
|
||||
<Compile Include="Interpreter\CapturedCode.cs" />
|
||||
<Compile Include="Interpreter\CodeRunner.cs" />
|
||||
<Compile Include="Interpreter\Emitter.cs" />
|
||||
<Compile Include="Interpreter\AxiomResult.cs" />
|
||||
|
||||
@@ -612,6 +612,7 @@ namespace Axiom.Interpreter
|
||||
lastMessage=exception.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void Negate()
|
||||
{
|
||||
try
|
||||
|
||||
17
Axiom.Core/Interpreter/CapturedCode.cs
Normal file
17
Axiom.Core/Interpreter/CapturedCode.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Axiom.Interpreter
|
||||
{
|
||||
public class CapturedCode
|
||||
{
|
||||
private readonly byte[] codeBytes;
|
||||
|
||||
public CapturedCode(byte[] codeBytes)
|
||||
{
|
||||
this.codeBytes = codeBytes ?? throw new ArgumentNullException(nameof(codeBytes));
|
||||
}
|
||||
public int Length => codeBytes.Length;
|
||||
|
||||
public byte[] Bytes => (byte[])codeBytes;
|
||||
}
|
||||
}
|
||||
@@ -29,10 +29,12 @@ namespace Axiom.Interpreter
|
||||
symbolTable=new SymbolTable();
|
||||
IsInError=false;
|
||||
}
|
||||
|
||||
~CodeRunner()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!disposed)
|
||||
@@ -41,6 +43,7 @@ namespace Axiom.Interpreter
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing)
|
||||
@@ -53,32 +56,40 @@ namespace Axiom.Interpreter
|
||||
}
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
public int ParseSymbolsCount
|
||||
{
|
||||
get{return parseSymbolCount;}
|
||||
}
|
||||
|
||||
public String LastMessage{ get; private set;}
|
||||
|
||||
public bool IsInError { get; private set;}
|
||||
|
||||
public bool ScanStrict
|
||||
{
|
||||
get{return scanStrict;}
|
||||
set{scanStrict=value;}
|
||||
}
|
||||
|
||||
public bool ParseStrict
|
||||
{
|
||||
get{return parseStrict;}
|
||||
set{parseStrict=value;}
|
||||
}
|
||||
|
||||
public bool Trace
|
||||
{
|
||||
get {return trace;}
|
||||
set {trace=value;}
|
||||
}
|
||||
|
||||
public bool UseCache
|
||||
{
|
||||
get { return useCache; }
|
||||
set { useCache = value; }
|
||||
}
|
||||
|
||||
public String GetValue(String name)
|
||||
{
|
||||
if (!symbolTable.ContainsKey(name)) return "null";
|
||||
@@ -87,6 +98,7 @@ namespace Axiom.Interpreter
|
||||
if (null == genericData || genericData.IsNull()) return "null";
|
||||
return genericData.Get<String>();
|
||||
}
|
||||
|
||||
public T GetValue<T>(String name)
|
||||
{
|
||||
if(!symbolTable.ContainsKey(name)) return default(T);
|
||||
@@ -95,20 +107,24 @@ namespace Axiom.Interpreter
|
||||
if(null==genericData||genericData.IsNull()) return default(T);
|
||||
return genericData.Get<T>();
|
||||
}
|
||||
|
||||
public SymbolTable SymbolTable
|
||||
{
|
||||
get {return symbolTable;}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (null == symbolTable) return;
|
||||
symbolTable.Reset();
|
||||
}
|
||||
|
||||
public bool Execute(DataTable dataTable, int row, String expression)
|
||||
{
|
||||
Reset();
|
||||
return ExecuteExpressionOnRow(dataTable, row, expression);
|
||||
}
|
||||
|
||||
private bool ExecuteExpressionOnRow(DataTable dataTable, int row, String expression)
|
||||
{
|
||||
symbolTable.AddUserSymbols(dataTable); // add symbol names from the data table columns
|
||||
@@ -123,6 +139,13 @@ namespace Axiom.Interpreter
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute - Executes the given expression. You can then use the helper methods.
|
||||
/// GetValue(String), GetValue<T>(String) to retrieve resulting variables from the symbolTable
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
public bool Execute(String expression)
|
||||
{
|
||||
BinaryReader binaryReader = null;
|
||||
@@ -161,7 +184,7 @@ namespace Axiom.Interpreter
|
||||
logger.ErrorFormat(LastMessage);
|
||||
return false;
|
||||
}
|
||||
parserWriter.BaseStream.Seek(0, SeekOrigin.Begin);
|
||||
parserWriter.BaseStream.Seek(0, SeekOrigin.Begin); // SEEK TO THE BEGINNING OF THE CODE
|
||||
assemblerReader = new BinaryReader(parserWriter.BaseStream);
|
||||
assembler = new Assembler(assemblerReader, symbolTable);
|
||||
assembler.Debug = Trace;
|
||||
@@ -196,6 +219,11 @@ namespace Axiom.Interpreter
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disassemble - This method does not execute code. It scans, parses, and disassembles the geenrated bytecode
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
public List<String> Disassemble(String expression)
|
||||
{
|
||||
BinaryReader binaryReader = null;
|
||||
@@ -210,9 +238,10 @@ namespace Axiom.Interpreter
|
||||
{
|
||||
IsInError=false;
|
||||
LastMessage="";
|
||||
SymbolTable localSymbolTable = new SymbolTable();
|
||||
binaryReader = new BinaryReader(Utility.StreamFromString(expression));
|
||||
binaryWriter = new BinaryWriter(new MemoryStream());
|
||||
Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable);
|
||||
Scanner scanner = new Scanner(binaryReader, binaryWriter, localSymbolTable);
|
||||
scanner.Debug = Trace;
|
||||
if (!scanner.Analyze())
|
||||
{
|
||||
@@ -224,7 +253,7 @@ namespace Axiom.Interpreter
|
||||
binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin);
|
||||
parserReader = new BinaryReader(binaryWriter.BaseStream);
|
||||
parserWriter = new BinaryWriter(new MemoryStream());
|
||||
Parser parser = new Parser(parserReader, parserWriter, symbolTable);
|
||||
Parser parser = new Parser(parserReader, parserWriter, localSymbolTable);
|
||||
parser.Debug = Trace;
|
||||
parser.Parse();
|
||||
parseSymbolCount=parser.ParseSymbolsCount;
|
||||
@@ -237,7 +266,7 @@ namespace Axiom.Interpreter
|
||||
}
|
||||
parserWriter.BaseStream.Seek(0, SeekOrigin.Begin);
|
||||
assemblerReader = new BinaryReader(parserWriter.BaseStream);
|
||||
assembler = new Assembler(assemblerReader, symbolTable);
|
||||
assembler = new Assembler(assemblerReader, localSymbolTable);
|
||||
assembler.Debug = Trace;
|
||||
return assembler.Disassemble();
|
||||
}
|
||||
@@ -412,7 +441,7 @@ namespace Axiom.Interpreter
|
||||
{
|
||||
logger.Info("********************************************************* O U T P U T ************************************************");
|
||||
List<Symbol> list = new List<Symbol>(symbolTable.Values);
|
||||
list = (from Symbol symbol in list where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserSymbol) select symbol).ToList();
|
||||
// list = (from Symbol symbol in list where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserSymbol) select symbol).ToList();
|
||||
foreach (Symbol symbol in list)
|
||||
{
|
||||
logger.Info(String.Format("SYMBOL NAME:'{0}',VALUE:'{1}'", symbol.SymbolName, null == symbol.GenericData ? "<null>" : symbol.GenericData.ToString()));
|
||||
|
||||
@@ -1,204 +1,248 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using log4net;
|
||||
|
||||
// FileName : Emitter.cs
|
||||
// Author : Sean Kessler
|
||||
using MarketData;
|
||||
|
||||
namespace Axiom.Interpreter
|
||||
{
|
||||
public class Emitter
|
||||
{
|
||||
private static ILog logger = LogManager.GetLogger(typeof(Emitter));
|
||||
private bool emitting = true;
|
||||
private int lastSymbol;
|
||||
private BinaryReader inputStream;
|
||||
private BinaryWriter outputStream;
|
||||
private BinaryWriter outputStream; // the assigned output stream
|
||||
private BinaryWriter activeStream; // the active stream
|
||||
private Stack<BinaryWriter> writeStack = new Stack<BinaryWriter>();
|
||||
private Stack<CapturedCode> captureStack = new Stack<CapturedCode>();
|
||||
private bool isCapturing = false;
|
||||
private bool debug = true;
|
||||
|
||||
public Emitter(BinaryReader inputStream, BinaryWriter outputStream)
|
||||
{
|
||||
this.inputStream = inputStream;
|
||||
this.outputStream = outputStream;
|
||||
this.activeStream = outputStream;
|
||||
}
|
||||
|
||||
public bool Debug
|
||||
{
|
||||
get { return debug; }
|
||||
set { debug = value; }
|
||||
}
|
||||
|
||||
public void BeginCapture()
|
||||
{
|
||||
writeStack.Push(activeStream);
|
||||
activeStream = new BinaryWriter(new MemoryStream());
|
||||
isCapturing = true;
|
||||
}
|
||||
|
||||
public void EndCapture()
|
||||
{
|
||||
if (!isCapturing)throw new InvalidOperationException("EndCapture called without a matching BeginCapture.");
|
||||
activeStream.Flush();
|
||||
MemoryStream memoryStream = (MemoryStream)activeStream.BaseStream;
|
||||
byte[] capturedBytes = memoryStream.ToArray();
|
||||
activeStream.Close();
|
||||
activeStream.Dispose();
|
||||
activeStream = writeStack.Pop();
|
||||
isCapturing = writeStack.Count > 0;
|
||||
captureStack.Push(new CapturedCode(capturedBytes));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EmitCapture - Later, for CONTINUE semantics, we can Peek() at the top of the captureStack to get the increment code without popping it.
|
||||
/// </summary>
|
||||
public void EmitCapture()
|
||||
{
|
||||
if(0==captureStack.Count)throw new InvalidOperationException("The CaptureList is empty.");
|
||||
CapturedCode code = captureStack.Pop();
|
||||
activeStream.Write(code.Bytes,0,code.Length);
|
||||
}
|
||||
|
||||
public void Emit(String literalValue)
|
||||
{
|
||||
if (!emitting) return;
|
||||
outputStream.Write(literalValue.Length);
|
||||
outputStream.Write(literalValue);
|
||||
activeStream.Write(literalValue.Length);
|
||||
activeStream.Write(literalValue);
|
||||
}
|
||||
// ************************************************************************
|
||||
|
||||
public void Emit(Scanner.ScanSymbols code)
|
||||
{
|
||||
if (!emitting) return;
|
||||
outputStream.Write((int)code);
|
||||
if(Debug)logger.Info(Scanner.SymbolToString(code));
|
||||
activeStream.Write((int)code);
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Scanner.SymbolToString(code));
|
||||
}
|
||||
|
||||
public void Emit(Scanner.ScanSymbols code,int value)
|
||||
{
|
||||
if (!emitting) return;
|
||||
outputStream.Write((int)code);
|
||||
outputStream.Write(value);
|
||||
if(Debug)logger.Info(Scanner.SymbolToString(code)+","+value.ToString());
|
||||
activeStream.Write((int)code);
|
||||
activeStream.Write(value);
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Scanner.SymbolToString(code) + "," + value.ToString());
|
||||
}
|
||||
|
||||
public void Emit(Scanner.ScanSymbols code,double value)
|
||||
{
|
||||
if (!emitting) return;
|
||||
outputStream.Write((int)code);
|
||||
outputStream.Write(value);
|
||||
if(Debug)logger.Info(Scanner.SymbolToString(code)+","+value.ToString());
|
||||
activeStream.Write((int)code);
|
||||
activeStream.Write(value);
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Scanner.SymbolToString(code) + "," + value.ToString());
|
||||
}
|
||||
|
||||
public void Emit(Scanner.ScanSymbols code,String value)
|
||||
{
|
||||
if (!emitting) return;
|
||||
outputStream.Write((int)code);
|
||||
outputStream.Write(value);
|
||||
if(Debug)logger.Info(Scanner.SymbolToString(code)+","+value.ToString());
|
||||
activeStream.Write((int)code);
|
||||
activeStream.Write(value);
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Scanner.SymbolToString(code) + "," + value.ToString());
|
||||
}
|
||||
// **********************************************************************************************************************************************
|
||||
public long CodePointer()
|
||||
{
|
||||
return outputStream.BaseStream.Position;
|
||||
|
||||
public long CodePointer()
|
||||
{
|
||||
return activeStream.BaseStream.Position;
|
||||
}
|
||||
public void Seek(long position)
|
||||
{
|
||||
outputStream.BaseStream.Seek(position, SeekOrigin.Begin);
|
||||
|
||||
public void Seek(long position)
|
||||
{
|
||||
activeStream.BaseStream.Seek(position, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public void Emit(Parser.ParserSymbols code)
|
||||
{
|
||||
if (!emitting) return;
|
||||
long positionBefore=outputStream.BaseStream.Position;
|
||||
outputStream.Write((int)code);
|
||||
long positionAfter=outputStream.BaseStream.Position;
|
||||
if(Debug)logger.Info(Parser.SymbolToString(code)+"["+positionBefore+","+positionAfter+"]");
|
||||
|
||||
long positionBefore = activeStream.BaseStream.Position;
|
||||
activeStream.Write((int)code);
|
||||
long positionAfter = activeStream.BaseStream.Position;
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Parser.SymbolToString(code) + "[" + positionBefore + "," + positionAfter + "]");
|
||||
}
|
||||
|
||||
public void Emit(Parser.ParserSymbols code,Object value)
|
||||
{
|
||||
if (!emitting) return;
|
||||
long positionBefore=outputStream.BaseStream.Position;
|
||||
outputStream.Write((int)code);
|
||||
long positionBefore = activeStream.BaseStream.Position;
|
||||
activeStream.Write((int)code);
|
||||
Type type = value.GetType();
|
||||
outputStream.Write(type.ToString());
|
||||
outputStream.Write(value.ToString());
|
||||
long positionAfter=outputStream.BaseStream.Position;
|
||||
if(Debug)logger.Info(Parser.SymbolToString(code)+","+type.ToString()+","+value.ToString()+"["+positionBefore+","+positionAfter+"]");
|
||||
activeStream.Write(type.ToString());
|
||||
activeStream.Write(value.ToString());
|
||||
long positionAfter = activeStream.BaseStream.Position;
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Parser.SymbolToString(code) + "," + type.ToString() + "," + value.ToString() + "[" + positionBefore + "," + positionAfter + "]");
|
||||
}
|
||||
|
||||
public void Emit(Parser.ParserSymbols code,Object value,int intValue)
|
||||
{
|
||||
if (!emitting) return;
|
||||
long positionBefore=outputStream.BaseStream.Position;
|
||||
outputStream.Write((int)code);
|
||||
long positionBefore = activeStream.BaseStream.Position;
|
||||
activeStream.Write((int)code);
|
||||
Type type = value.GetType();
|
||||
outputStream.Write(type.ToString());
|
||||
outputStream.Write(value.ToString());
|
||||
outputStream.Write(intValue);
|
||||
long positionAfter=outputStream.BaseStream.Position;
|
||||
if(Debug)logger.Info(Parser.SymbolToString(code)+","+type.ToString()+","+value.ToString()+","+intValue+"["+positionBefore+","+positionAfter+"]");
|
||||
activeStream.Write(type.ToString());
|
||||
activeStream.Write(value.ToString());
|
||||
activeStream.Write(intValue);
|
||||
long positionAfter = activeStream.BaseStream.Position;
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Parser.SymbolToString(code) + "," + type.ToString() + "," + value.ToString() + "," + intValue + "[" + positionBefore + "," + positionAfter + "]");
|
||||
}
|
||||
|
||||
public void Emit(Parser.ParserSymbols code,long value)
|
||||
{
|
||||
if (!emitting) return;
|
||||
long positionBefore=outputStream.BaseStream.Position;
|
||||
outputStream.Write((int)code);
|
||||
outputStream.Write(value);
|
||||
long positionAfter=outputStream.BaseStream.Position;
|
||||
if(Debug)logger.Info(Parser.SymbolToString(code)+","+value.ToString()+","+value.ToString()+"["+positionBefore+","+positionAfter+"]");
|
||||
long positionBefore = activeStream.BaseStream.Position;
|
||||
activeStream.Write((int)code);
|
||||
activeStream.Write(value);
|
||||
long positionAfter = activeStream.BaseStream.Position;
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Parser.SymbolToString(code) + "," + value.ToString() + "," + value.ToString() + "[" + positionBefore + "," + positionAfter + "]");
|
||||
}
|
||||
|
||||
public void EmitAsNull(Parser.ParserSymbols code)
|
||||
{
|
||||
if (!emitting) return;
|
||||
long positionBefore=outputStream.BaseStream.Position;
|
||||
outputStream.Write((int)code);
|
||||
Type type = typeof(System.Nullable); //value.GetType();
|
||||
outputStream.Write(type.ToString());
|
||||
outputStream.Write("null".ToString());
|
||||
long positionAfter=outputStream.BaseStream.Position;
|
||||
if(Debug)logger.Info(Parser.SymbolToString(code)+","+type.ToString()+","+"null".ToString()+"["+positionBefore+","+positionAfter+"]");
|
||||
long positionBefore = activeStream.BaseStream.Position;
|
||||
activeStream.Write((int)code);
|
||||
Type type = typeof(System.Nullable);
|
||||
activeStream.Write(type.ToString());
|
||||
activeStream.Write("null".ToString());
|
||||
long positionAfter = activeStream.BaseStream.Position;
|
||||
if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Parser.SymbolToString(code) + "," + type.ToString() + "," + "null" + "[" + positionBefore + "," + positionAfter + "]");
|
||||
}
|
||||
// ************************************************************************
|
||||
public void Emit(int code, int op)
|
||||
|
||||
public void Emit(int code,int op)
|
||||
{
|
||||
if (!emitting) return;
|
||||
outputStream.Write(code);
|
||||
outputStream.Write(op);
|
||||
activeStream.Write(code);
|
||||
activeStream.Write(op);
|
||||
}
|
||||
|
||||
public void Emit(int identifier)
|
||||
{
|
||||
if (!emitting) return;
|
||||
outputStream.Write(identifier);
|
||||
activeStream.Write(identifier);
|
||||
}
|
||||
|
||||
public void Emit(byte value)
|
||||
{
|
||||
if (!emitting) return;
|
||||
outputStream.Write(value);
|
||||
activeStream.Write(value);
|
||||
}
|
||||
|
||||
public int Peek(ref int value)
|
||||
{
|
||||
value = inputStream.PeekChar();
|
||||
return value;
|
||||
}
|
||||
|
||||
public int Peek()
|
||||
{
|
||||
int value = inputStream.PeekChar();
|
||||
return value;
|
||||
}
|
||||
|
||||
public int PeekIgnore(ref int value,int[] ignoreChars)
|
||||
{
|
||||
long streamPosition = inputStream.BaseStream.Position;
|
||||
while (true)
|
||||
{
|
||||
int readValue = (int)inputStream.ReadChar();
|
||||
value = readValue;
|
||||
if (!ignoreChars.Any(x => x.Equals(readValue))) break;
|
||||
}
|
||||
inputStream.BaseStream.Seek(streamPosition, SeekOrigin.Begin);
|
||||
return value;
|
||||
}
|
||||
public int Peek(ref int value)
|
||||
{
|
||||
value = inputStream.PeekChar();
|
||||
return value;
|
||||
}
|
||||
public int Peek()
|
||||
{
|
||||
int value = inputStream.PeekChar();
|
||||
return value;
|
||||
}
|
||||
|
||||
public int PeekIgnore(ref int value,int[] ignoreChars)
|
||||
{
|
||||
long streamPosition=inputStream.BaseStream.Position;
|
||||
while(true)
|
||||
{
|
||||
int readValue;
|
||||
readValue=(int)inputStream.ReadChar();
|
||||
value=readValue;
|
||||
if(!ignoreChars.Any(x=>x.Equals(readValue)))break;
|
||||
}
|
||||
inputStream.BaseStream.Seek(streamPosition,SeekOrigin.Begin);
|
||||
return value;
|
||||
}
|
||||
public int Read()
|
||||
{
|
||||
lastSymbol = inputStream.Read();
|
||||
return lastSymbol;
|
||||
}
|
||||
|
||||
public int Read(ref String literal)
|
||||
{
|
||||
literal=inputStream.ReadString();
|
||||
literal = inputStream.ReadString();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int Read(ref byte value)
|
||||
{
|
||||
try { value = inputStream.ReadByte(); return 0; }
|
||||
catch (EndOfStreamException) { return 0xFFFF; }
|
||||
}
|
||||
|
||||
public int Read(ref int value)
|
||||
{
|
||||
try { value = inputStream.ReadInt32(); return 0; }
|
||||
catch (EndOfStreamException) { return 0xFFFF; }
|
||||
|
||||
}
|
||||
|
||||
public int Read(ref double value)
|
||||
{
|
||||
try { value = inputStream.ReadDouble(); return 0; }
|
||||
catch (EndOfStreamException) { return 0xFFFF; }
|
||||
}
|
||||
|
||||
public bool Emitting
|
||||
{
|
||||
get
|
||||
{
|
||||
return emitting;
|
||||
}
|
||||
set
|
||||
{
|
||||
emitting = value;
|
||||
}
|
||||
get { return emitting; }
|
||||
set { emitting = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
|
||||
// FileName : Parser.cs
|
||||
// Author : Sean Kessler
|
||||
@@ -34,7 +35,7 @@ namespace Axiom.Interpreter
|
||||
private String stringValue;
|
||||
private bool strictStatementMode=false; // is StrictStatementMode is true then the parser will return an error if there is not at least one statement processed.
|
||||
private Stack<long> breakStack = new Stack<long>(); // when we encounter a break statement we need to record the address of the code pointer
|
||||
private Stack<bool> whileStack = new Stack<bool>(); // when we encounter a while statement we need to record the event so that we can validate any break statements
|
||||
private Stack<bool> loopStack = new Stack<bool>(); // when we encounter a loop (while/for) statement we need to record the event so that we can validate any break statements
|
||||
|
||||
public Parser(BinaryReader binaryReader, BinaryWriter binaryWriter, SymbolTable symbolTable)
|
||||
: base(binaryReader, binaryWriter)
|
||||
@@ -135,11 +136,16 @@ namespace Axiom.Interpreter
|
||||
BreakStatement();
|
||||
StatementNumber++;
|
||||
}
|
||||
else if (Scanner.ScanSymbols.while1.Equals(currentSymbolType))
|
||||
else if (Scanner.ScanSymbols.while1.Equals(currentSymbolType))
|
||||
{
|
||||
WhileStatement();
|
||||
StatementNumber++;
|
||||
}
|
||||
else if (Scanner.ScanSymbols.for1.Equals(currentSymbolType))
|
||||
{
|
||||
ForStatement();
|
||||
StatementNumber++;
|
||||
}
|
||||
else if (SymbolIn(termSymbols))
|
||||
{
|
||||
Term();
|
||||
@@ -157,6 +163,7 @@ namespace Axiom.Interpreter
|
||||
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1));
|
||||
return;
|
||||
}
|
||||
|
||||
public void DeclarationStatement()
|
||||
{
|
||||
bool moreDeclarations = true;
|
||||
@@ -178,21 +185,24 @@ namespace Axiom.Interpreter
|
||||
}
|
||||
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
||||
}
|
||||
|
||||
public void DirectiveClearModified()
|
||||
{
|
||||
Emit(Parser.ParserSymbols.directive_clear_modified2);
|
||||
Expect(Scanner.ScanSymbols.directive_clear_modified1);
|
||||
}
|
||||
|
||||
public void ParseLiteral()
|
||||
{
|
||||
Emit(Parser.ParserSymbols.push2, stringValue);
|
||||
Expect(Scanner.ScanSymbols.literal1);
|
||||
}
|
||||
|
||||
public void BreakStatement()
|
||||
{
|
||||
if(0.Equals(whileStack.Count))
|
||||
if(0.Equals(loopStack.Count))
|
||||
{
|
||||
SyntaxError("Encountered 'break' without 'while'");
|
||||
SyntaxError("Encountered 'break' without 'while'/'for'");
|
||||
}
|
||||
if(breakStack.Count>0)
|
||||
{
|
||||
@@ -205,6 +215,267 @@ namespace Axiom.Interpreter
|
||||
breakStack.Push(CodePointer());
|
||||
Expect(Scanner.ScanSymbols.break1);
|
||||
}
|
||||
// ********************************************************************************************************************************
|
||||
// *************************************************** F O R S T A T E M E N T *************************************************
|
||||
// ********************************************************************************************************************************
|
||||
//INIT
|
||||
//L1:
|
||||
// CONDITION
|
||||
// IF FALSE -> L2
|
||||
//BODY
|
||||
//INCREMENT
|
||||
//GOTO L1
|
||||
//L2: NOOP
|
||||
public void ForStatement()
|
||||
{
|
||||
long codePointerL1;
|
||||
long codePointerFalseBranch;
|
||||
long codePointerL2;
|
||||
long codePointerTerminalAddress;
|
||||
|
||||
loopStack.Push(true); // register this is a for loop
|
||||
InsertSymbols(expressionSymbols);
|
||||
InsertSymbols(directiveSymbols);
|
||||
Expect(Scanner.ScanSymbols.for1);
|
||||
Expect(Scanner.ScanSymbols.leftparen1);
|
||||
RemoveSymbols(expressionSymbols);
|
||||
RemoveSymbols(directiveSymbols);
|
||||
if (IsInError) { loopStack.Pop(); return; }
|
||||
DoInitialization(); // Do initialization. I=1
|
||||
codePointerL1 = CodePointer(); // execution target codePointerL1
|
||||
DoForCondition(); // e.g., I < 10 // emit the for condition
|
||||
codePointerFalseBranch = CodePointer(); // get the location in the stream for the defaddr2 that follows
|
||||
Emit(Parser.ParserSymbols.defaddr2, 0L); // emit defaddr2 (jump if false) with dummy address of 0L
|
||||
BeginCapture(); // start a new code emit frame
|
||||
DoForIncrement(); // emit the increment code e.g., I = I + 1
|
||||
EndCapture(); // end the capture and retrieve the emitted code
|
||||
DoForBlock(); // emit the BODY
|
||||
EmitCapture(); // emit the code block we captured above between BeginCapture and EndCapture
|
||||
if (IsInError) { loopStack.Pop(); return; } // check error condition
|
||||
Emit(Parser.ParserSymbols.goto2, codePointerL1); // jump back to condition after the body
|
||||
codePointerL2 = CodePointer(); // get the location in the stream for the L2 exit location
|
||||
Emit(Parser.ParserSymbols.noop2); // emit a noop at the current location
|
||||
codePointerTerminalAddress = CodePointer(); // Record code pointer before seeking
|
||||
Seek(codePointerFalseBranch); // seek to the defaddr2 statement that we emitted above
|
||||
Emit(Parser.ParserSymbols.defaddr2, codePointerL2); // rewrite that statement with the correct branch address of L2 exit marker
|
||||
HandleBreak(codePointerL2); // Handle any breaks
|
||||
Seek(codePointerTerminalAddress); // seek to Terminal address in order to leave the stream at the correct location at the end of this all.
|
||||
loopStack.Pop();
|
||||
}
|
||||
|
||||
private void DoForIncrement()
|
||||
{
|
||||
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
||||
InsertSymbols(statementSymbols);
|
||||
Expect(Scanner.ScanSymbols.semicolon1);
|
||||
Statement();
|
||||
RemoveSymbols(statementSymbols);
|
||||
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
||||
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
||||
Expect(Scanner.ScanSymbols.rightparen1);
|
||||
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
||||
}
|
||||
|
||||
private void DoForBlock()
|
||||
{
|
||||
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
||||
InsertSymbols(statementSymbols);
|
||||
Expect(Scanner.ScanSymbols.leftcurly1); // at this point we have {
|
||||
if(IsInError)return;
|
||||
while(!SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)) && !IsInError)
|
||||
{
|
||||
Statement();
|
||||
}
|
||||
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
||||
Expect(Scanner.ScanSymbols.rightcurly1);
|
||||
if(IsInError)return;
|
||||
RemoveSymbols(statementSymbols);
|
||||
}
|
||||
|
||||
|
||||
private void DoForCondition()
|
||||
{
|
||||
long enterSymbolCount = SymbolCount();
|
||||
Stack<Parser.ParserSymbols> logicalOperatorStack = new Stack<Parser.ParserSymbols>();
|
||||
|
||||
while (!IsInError)
|
||||
{
|
||||
// Stop at the increment separator
|
||||
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))
|
||||
break;
|
||||
|
||||
bool inShortFunction = false;
|
||||
InsertSymbols(expressionSymbols);
|
||||
if (PeekSymbolIn(directiveSymbols)) inShortFunction = true;
|
||||
|
||||
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.semicolon1));
|
||||
InsertSymbols(logicalSymbols);
|
||||
|
||||
// Parse left-hand side expression and relation
|
||||
Expression();
|
||||
Relation();
|
||||
|
||||
InsertSymbols(relationSymbols);
|
||||
SyntaxCheck();
|
||||
if (IsInError) return;
|
||||
|
||||
RemoveSymbols(relationSymbols);
|
||||
RemoveSymbols(logicalSymbols);
|
||||
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.semicolon1));
|
||||
|
||||
// Handle short functions or logical chaining
|
||||
if (inShortFunction || SymbolIn(logicalSymbols))
|
||||
{
|
||||
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
||||
{
|
||||
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
||||
InsertSymbols(expressionSymbols);
|
||||
InsertSymbols(directiveSymbols);
|
||||
Expect(currentSymbolType);
|
||||
RemoveSymbols(expressionSymbols);
|
||||
RemoveSymbols(expressionSymbols); // yes, twice
|
||||
RemoveSymbols(directiveSymbols);
|
||||
continue;
|
||||
}
|
||||
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
||||
{
|
||||
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
||||
InsertSymbols(expressionSymbols);
|
||||
InsertSymbols(directiveSymbols);
|
||||
Expect(currentSymbolType);
|
||||
RemoveSymbols(expressionSymbols);
|
||||
RemoveSymbols(expressionSymbols); // yes, twice
|
||||
RemoveSymbols(directiveSymbols);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop if next symbol is semicolon (increment)
|
||||
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))
|
||||
{
|
||||
RemoveSymbols(expressionSymbols);
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse relational operator
|
||||
ParseSymbol relationSymbol = new ParseSymbol(currentSymbolType);
|
||||
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
||||
InsertSymbols(logicalSymbols);
|
||||
InsertSymbols(directiveSymbols);
|
||||
Expect(currentSymbolType);
|
||||
if (IsInError) return;
|
||||
|
||||
RemoveSymbols(expressionSymbols);
|
||||
RemoveSymbols(directiveSymbols);
|
||||
|
||||
if (!inShortFunction)
|
||||
{
|
||||
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
||||
|
||||
if (SymbolIn(directiveSymbols))
|
||||
{
|
||||
InsertSymbols(relationSymbols);
|
||||
Directive();
|
||||
Relation();
|
||||
RemoveSymbols(relationSymbols);
|
||||
}
|
||||
|
||||
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
||||
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1)))
|
||||
Expect(Scanner.ScanSymbols.rightparen1);
|
||||
|
||||
EmitRelation(relationSymbol);
|
||||
}
|
||||
|
||||
// Emit any logical operators in stack
|
||||
if (logicalOperatorStack.Count != 0)
|
||||
Emit(logicalOperatorStack.Pop());
|
||||
|
||||
// Check for trailing logical operators
|
||||
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
||||
{
|
||||
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
||||
InsertSymbols(expressionSymbols);
|
||||
InsertSymbols(directiveSymbols);
|
||||
Expect(currentSymbolType);
|
||||
RemoveSymbols(expressionSymbols);
|
||||
RemoveSymbols(directiveSymbols);
|
||||
}
|
||||
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
||||
{
|
||||
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
||||
InsertSymbols(expressionSymbols);
|
||||
InsertSymbols(directiveSymbols);
|
||||
Expect(currentSymbolType);
|
||||
RemoveSymbols(expressionSymbols);
|
||||
RemoveSymbols(directiveSymbols);
|
||||
}
|
||||
|
||||
RemoveSymbols(logicalSymbols);
|
||||
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
||||
RemoveSymbols(expressionSymbols);
|
||||
|
||||
if (!SymbolIn(expressionSymbols) && !SymbolIn(directiveSymbols))
|
||||
break;
|
||||
}
|
||||
|
||||
// Emit remaining logical operators
|
||||
while (logicalOperatorStack.Count > 0)
|
||||
Emit(logicalOperatorStack.Pop());
|
||||
|
||||
// Check symbol stack consistency
|
||||
long exitSymbolCount = SymbolCount();
|
||||
if (enterSymbolCount != exitSymbolCount)
|
||||
throw new InvalidOperationException("Symbol counts do not match");
|
||||
}
|
||||
|
||||
private void EmitRelation(ParseSymbol relationSymbol)
|
||||
{
|
||||
if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.notequal1)))
|
||||
{
|
||||
Emit(Parser.ParserSymbols.notequal2);
|
||||
}
|
||||
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.equalequal1)))
|
||||
{
|
||||
Emit(Parser.ParserSymbols.equalequal2);
|
||||
}
|
||||
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.less1)))
|
||||
{
|
||||
Emit(Parser.ParserSymbols.less2);
|
||||
}
|
||||
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.lessequal1)))
|
||||
{
|
||||
Emit(Parser.ParserSymbols.lessequal2);
|
||||
}
|
||||
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.greater1)))
|
||||
{
|
||||
Emit(Parser.ParserSymbols.greater2);
|
||||
}
|
||||
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.greaterequal1)))
|
||||
{
|
||||
Emit(Parser.ParserSymbols.greaterequal2);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoInitialization()
|
||||
{
|
||||
// for (; ... ) → empty initialization
|
||||
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))return;
|
||||
// Reuse your normal assignment parser
|
||||
Statement();
|
||||
}
|
||||
|
||||
private void DoIncrement()
|
||||
{
|
||||
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Expression();
|
||||
}
|
||||
// ********************************************************************************************************************************
|
||||
// ************************************************** W H I L E S T A T E M E N T **********************************************
|
||||
// ********************************************************************************************************************************
|
||||
/// <summary>
|
||||
/// WhileStatement Parses WhileStatement.
|
||||
///WHILE
|
||||
@@ -221,36 +492,42 @@ namespace Axiom.Interpreter
|
||||
long codePointerL2;
|
||||
long codePointerTerminalAddress;
|
||||
|
||||
whileStack.Push(true); // Register that we are processing a while loop
|
||||
loopStack.Push(true); // Register that we are processing a while loop
|
||||
InsertSymbols(expressionSymbols);
|
||||
InsertSymbols(directiveSymbols);
|
||||
Expect(Scanner.ScanSymbols.while1);
|
||||
Expect(Scanner.ScanSymbols.leftparen1);
|
||||
RemoveSymbols(expressionSymbols);
|
||||
RemoveSymbols(directiveSymbols);
|
||||
if (IsInError){whileStack.Pop(); return;}
|
||||
if (IsInError){loopStack.Pop(); return;}
|
||||
codePointerL1 = CodePointer(); // L1:
|
||||
DoBForWhile(); // B
|
||||
if(IsInError){whileStack.Pop(); return;}
|
||||
if(IsInError){loopStack.Pop(); return;}
|
||||
codePointerFalseInstructionAddress = CodePointer(); // Record the location of the DEFADDR2 instruction.
|
||||
Emit(Parser.ParserSymbols.defaddr2,0L); // Write DEFADDR2,0L. This will be jump to condition:false
|
||||
DoSForWhile(); // S
|
||||
if(IsInError){whileStack.Pop(); return;}
|
||||
if(IsInError){loopStack.Pop(); return;}
|
||||
Emit(Parser.ParserSymbols.goto2,codePointerL1); // Goto(L1)
|
||||
codePointerL2=CodePointer(); // L2:
|
||||
Emit(Parser.ParserSymbols.noop2); // Don't write any instructions past this point
|
||||
codePointerTerminalAddress=CodePointer(); // Record code pointer before seeking
|
||||
Seek(codePointerFalseInstructionAddress); // Seek to DEFADDR2 instruction
|
||||
Emit(Parser.ParserSymbols.defaddr2,codePointerL2); // Write DEFADDR2, L2
|
||||
HandleBreak(codePointerL2); // If there was a break statement then handle to jump condition
|
||||
HandleBreak(codePointerL2); // If there was a break statement then handle the jump to condition
|
||||
Seek(codePointerTerminalAddress);
|
||||
loopStack.Pop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the handling for break statements in while loops
|
||||
/// For the while statement there will be a DEFADDR, L2 just prior to a NOOP
|
||||
/// </summary>
|
||||
/// <param name="codePointerL2"></param>
|
||||
public void HandleBreak(long codePointerL2)
|
||||
{
|
||||
if(0==breakStack.Count)return;
|
||||
Seek(breakStack.Pop());
|
||||
Emit(Parser.ParserSymbols.goto2,codePointerL2);
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// B Section for While.
|
||||
@@ -1499,6 +1776,12 @@ namespace Axiom.Interpreter
|
||||
else SyntaxError(symbol);
|
||||
SyntaxCheck();
|
||||
}
|
||||
|
||||
public long SymbolCount()
|
||||
{
|
||||
return parseSymbols.Count;
|
||||
}
|
||||
|
||||
public void InsertSymbols(ParseSymbols groupSymbols)
|
||||
{
|
||||
parseSymbols.InsertSymbols(groupSymbols);
|
||||
@@ -1600,6 +1883,7 @@ namespace Axiom.Interpreter
|
||||
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
||||
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.if1));
|
||||
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.while1));
|
||||
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.for1));
|
||||
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.declare1));
|
||||
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.break1));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ namespace Axiom.Interpreter
|
||||
{
|
||||
public class Scanner : Emitter
|
||||
{
|
||||
public enum ScanSymbols { unknown1, directive_clear_modified1,declare1, null1, isnull1, convert1, getprice1, substring1, in1, like1, trim1, upper1, lower1, assign1, if1, while1, then1,else1,goto1,equal1,equalequal1,less1,lessequal1,greater1,greaterequal1, notequal1,variable1, asterisk1, apostrophe1, comma1, label1, literal1, leftcurly1, rightcurly1, leftbracket1, rightbracket1, numeral1, char1, divide1, plus1, minus1, leftparen1, rightparen1, newline1, semicolon1,endtext1, andand1, oror1, abs1, not1, pow1, sqrt1, break1, end1 };
|
||||
public enum ScanSymbols { unknown1, directive_clear_modified1,declare1, null1, isnull1, convert1,
|
||||
getprice1, substring1, in1, like1, trim1, upper1, lower1, assign1, if1, while1, for1, then1, else1, goto1,
|
||||
equal1, equalequal1, less1, lessequal1, greater1, greaterequal1, notequal1, variable1, asterisk1, apostrophe1,
|
||||
comma1, label1, literal1, leftcurly1, rightcurly1, leftbracket1, rightbracket1, numeral1, char1, divide1, plus1,
|
||||
minus1, leftparen1, rightparen1, newline1, semicolon1,endtext1, andand1, oror1, abs1, not1, pow1, sqrt1, break1, end1 };
|
||||
private enum WhiteSpace{spacechar=32,tabchar=9};
|
||||
private int character;
|
||||
private StringBuilder word;
|
||||
@@ -409,6 +413,8 @@ namespace Axiom.Interpreter
|
||||
return "if";
|
||||
case Scanner.ScanSymbols.while1 :
|
||||
return "while";
|
||||
case Scanner.ScanSymbols.for1 :
|
||||
return "for";
|
||||
case Scanner.ScanSymbols.then1 :
|
||||
return "then";
|
||||
case Scanner.ScanSymbols.else1 :
|
||||
@@ -523,6 +529,8 @@ namespace Axiom.Interpreter
|
||||
return "if1";
|
||||
case Scanner.ScanSymbols.while1 :
|
||||
return "while1";
|
||||
case Scanner.ScanSymbols.for1 :
|
||||
return "for1";
|
||||
case Scanner.ScanSymbols.then1 :
|
||||
return "then1";
|
||||
case Scanner.ScanSymbols.else1 :
|
||||
|
||||
@@ -140,6 +140,7 @@ namespace Axiom.Interpreter
|
||||
Add("if",new Symbol("if",Scanner.ScanSymbols.if1,Symbol.SymbolType.KeywordSymbol));
|
||||
Add("break",new Symbol("break",Scanner.ScanSymbols.break1,Symbol.SymbolType.KeywordSymbol));
|
||||
Add("while",new Symbol("while",Scanner.ScanSymbols.while1,Symbol.SymbolType.KeywordSymbol));
|
||||
Add("for",new Symbol("for",Scanner.ScanSymbols.for1,Symbol.SymbolType.KeywordSymbol));
|
||||
Add("then", new Symbol("then", Scanner.ScanSymbols.then1, Symbol.SymbolType.KeywordSymbol));
|
||||
Add("else", new Symbol("else", Scanner.ScanSymbols.else1, Symbol.SymbolType.KeywordSymbol));
|
||||
Add("and", new Symbol("and", Scanner.ScanSymbols.andand1, Symbol.SymbolType.KeywordSymbol));
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AxiomConsole</RootNamespace>
|
||||
<AssemblyName>AxiomConsole</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -22,52 +22,61 @@ namespace AxiomConsole
|
||||
// IF(A==1)THEN BREAK;
|
||||
// A=A+1;
|
||||
// }";
|
||||
String expression=@"
|
||||
A=1;
|
||||
B=1;
|
||||
C=1;
|
||||
D=1;
|
||||
WHILE(A<10)
|
||||
{
|
||||
WHILE(B<10)
|
||||
//String expression = @"
|
||||
// J=1;
|
||||
// FOR(I=1;I<10;I=I+1)
|
||||
// {
|
||||
// J=J+10;
|
||||
// break;
|
||||
// }
|
||||
// ";
|
||||
|
||||
//String expression = @"
|
||||
// J=1;
|
||||
// FOR(I=1;I<10;I=I+1)
|
||||
// {
|
||||
// J=J+10;
|
||||
// }
|
||||
// ";
|
||||
|
||||
String expression = @"
|
||||
DECLARE A,J,TOTAL;
|
||||
A=1;
|
||||
J=1;
|
||||
TOTAL=0;
|
||||
FOR(A=1;A<=10;A=A+1)
|
||||
{
|
||||
WHILE(C<10)
|
||||
FOR(J=1;J<=10;J=J+1)
|
||||
{
|
||||
WHILE(D<10)
|
||||
{
|
||||
A=A+1;
|
||||
B=B+1;
|
||||
C=C+1;
|
||||
D=D+1;
|
||||
IF(D==10)THEN BREAK;
|
||||
BREAK;
|
||||
}
|
||||
BREAK;
|
||||
TOTAL=TOTAL+1
|
||||
}
|
||||
BREAK;
|
||||
}
|
||||
BREAK;
|
||||
}";
|
||||
";
|
||||
|
||||
|
||||
CodeRunner codeRunner = new CodeRunner();
|
||||
codeRunner.Trace=true;
|
||||
//if (!codeRunner.Execute(expression))
|
||||
//{
|
||||
// Console.WriteLine("CodeRunner Failed with {0}", codeRunner.LastMessage);
|
||||
// Console.Read();
|
||||
//}
|
||||
|
||||
List<String> disassembly=codeRunner.Disassemble(expression);
|
||||
if(codeRunner.IsInError)
|
||||
{
|
||||
Console.WriteLine("CodeRunner Failed with {0}",codeRunner.LastMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(expression);
|
||||
foreach(String line in disassembly)
|
||||
{
|
||||
Console.WriteLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> disassembly = codeRunner.Disassemble(expression);
|
||||
if (codeRunner.IsInError)
|
||||
{
|
||||
Console.WriteLine("CodeRunner Failed with {0}", codeRunner.LastMessage);
|
||||
} else
|
||||
{
|
||||
Console.WriteLine(expression);
|
||||
foreach (String line in disassembly)
|
||||
{
|
||||
Console.WriteLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
Console.Read();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="market_data" value="Database=market_data;Datasource=localhost;Username=root;Password=dbas"/>
|
||||
@@ -6,6 +6,6 @@
|
||||
|
||||
</appSettings>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
||||
@@ -176,6 +176,71 @@ namespace AxiomUnitTestProject
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("B").Equals(5));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ForStatementVariant3()
|
||||
{
|
||||
String expression=@"
|
||||
DECLARE A,J,TOTAL;
|
||||
A=1;
|
||||
J=1;
|
||||
TOTAL=0;
|
||||
FOR(A=1;A<=10;A=A+1)
|
||||
{
|
||||
FOR(J=1;J<=10;J=J+1)
|
||||
{
|
||||
BREAK;
|
||||
TOTAL=TOTAL+1
|
||||
}
|
||||
}
|
||||
";
|
||||
CodeRunner codeRunner = new CodeRunner();
|
||||
Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage);
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("J").Equals(1));
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("A").Equals(11));
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("TOTAL").Equals(0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ForStatementVariant2()
|
||||
{
|
||||
String expression=@"
|
||||
DECLARE A,J,TOTAL;
|
||||
A=1;
|
||||
J=1;
|
||||
TOTAL=0;
|
||||
FOR(A=1;A<=10;A=A+1)
|
||||
{
|
||||
FOR(J=1;J<=10;J=J+1)
|
||||
{
|
||||
TOTAL=TOTAL+1;
|
||||
}
|
||||
}
|
||||
";
|
||||
CodeRunner codeRunner = new CodeRunner();
|
||||
Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage);
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("J").Equals(11));
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("A").Equals(11));
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("TOTAL").Equals(100));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ForStatementVariant1()
|
||||
{
|
||||
String expression=@"
|
||||
DECLARE A,J;
|
||||
A=1;
|
||||
J=1;
|
||||
FOR(A=1;A<10;A=A+1)
|
||||
{
|
||||
J=J+1;
|
||||
}
|
||||
";
|
||||
CodeRunner codeRunner = new CodeRunner();
|
||||
Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage);
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("J").Equals(10));
|
||||
Assert.IsTrue(codeRunner.GetValue<double>("A").Equals(10));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WhileStatementVariant4()
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AxiomUnitTestProjectr</RootNamespace>
|
||||
<AssemblyName>AxiomUnitTestProjectr</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
|
||||
Reference in New Issue
Block a user