4 Commits

20 changed files with 617 additions and 158 deletions

View File

@@ -8,7 +8,7 @@
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<RootNamespace>Axiom.Core</RootNamespace> <RootNamespace>Axiom.Core</RootNamespace>
<AssemblyName>Axiom.Core</AssemblyName> <AssemblyName>Axiom.Core</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@@ -64,6 +64,7 @@
<Compile Include="Interpreter\Assembler.cs" /> <Compile Include="Interpreter\Assembler.cs" />
<Compile Include="Interpreter\AxiomException.cs" /> <Compile Include="Interpreter\AxiomException.cs" />
<Compile Include="Interpreter\AxiomTrace.cs" /> <Compile Include="Interpreter\AxiomTrace.cs" />
<Compile Include="Interpreter\CapturedCode.cs" />
<Compile Include="Interpreter\CodeRunner.cs" /> <Compile Include="Interpreter\CodeRunner.cs" />
<Compile Include="Interpreter\Emitter.cs" /> <Compile Include="Interpreter\Emitter.cs" />
<Compile Include="Interpreter\AxiomResult.cs" /> <Compile Include="Interpreter\AxiomResult.cs" />

View File

@@ -612,6 +612,7 @@ namespace Axiom.Interpreter
lastMessage=exception.ToString(); lastMessage=exception.ToString();
} }
} }
private void Negate() private void Negate()
{ {
try try

View 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;
}
}

View File

@@ -29,10 +29,12 @@ namespace Axiom.Interpreter
symbolTable=new SymbolTable(); symbolTable=new SymbolTable();
IsInError=false; IsInError=false;
} }
~CodeRunner() ~CodeRunner()
{ {
Dispose(false); Dispose(false);
} }
public void Dispose() public void Dispose()
{ {
if (!disposed) if (!disposed)
@@ -41,6 +43,7 @@ namespace Axiom.Interpreter
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
} }
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if(disposing) if(disposing)
@@ -53,32 +56,40 @@ namespace Axiom.Interpreter
} }
disposed = true; disposed = true;
} }
public int ParseSymbolsCount public int ParseSymbolsCount
{ {
get{return parseSymbolCount;} get{return parseSymbolCount;}
} }
public String LastMessage{ get; private set;} public String LastMessage{ get; private set;}
public bool IsInError { get; private set;} public bool IsInError { get; private set;}
public bool ScanStrict public bool ScanStrict
{ {
get{return scanStrict;} get{return scanStrict;}
set{scanStrict=value;} set{scanStrict=value;}
} }
public bool ParseStrict public bool ParseStrict
{ {
get{return parseStrict;} get{return parseStrict;}
set{parseStrict=value;} set{parseStrict=value;}
} }
public bool Trace public bool Trace
{ {
get {return trace;} get {return trace;}
set {trace=value;} set {trace=value;}
} }
public bool UseCache public bool UseCache
{ {
get { return useCache; } get { return useCache; }
set { useCache = value; } set { useCache = value; }
} }
public String GetValue(String name) public String GetValue(String name)
{ {
if (!symbolTable.ContainsKey(name)) return "null"; if (!symbolTable.ContainsKey(name)) return "null";
@@ -87,6 +98,7 @@ namespace Axiom.Interpreter
if (null == genericData || genericData.IsNull()) return "null"; if (null == genericData || genericData.IsNull()) return "null";
return genericData.Get<String>(); return genericData.Get<String>();
} }
public T GetValue<T>(String name) public T GetValue<T>(String name)
{ {
if(!symbolTable.ContainsKey(name)) return default(T); if(!symbolTable.ContainsKey(name)) return default(T);
@@ -95,20 +107,24 @@ namespace Axiom.Interpreter
if(null==genericData||genericData.IsNull()) return default(T); if(null==genericData||genericData.IsNull()) return default(T);
return genericData.Get<T>(); return genericData.Get<T>();
} }
public SymbolTable SymbolTable public SymbolTable SymbolTable
{ {
get {return symbolTable;} get {return symbolTable;}
} }
public void Reset() public void Reset()
{ {
if (null == symbolTable) return; if (null == symbolTable) return;
symbolTable.Reset(); symbolTable.Reset();
} }
public bool Execute(DataTable dataTable, int row, String expression) public bool Execute(DataTable dataTable, int row, String expression)
{ {
Reset(); Reset();
return ExecuteExpressionOnRow(dataTable, row, expression); return ExecuteExpressionOnRow(dataTable, row, expression);
} }
private bool ExecuteExpressionOnRow(DataTable dataTable, int row, String expression) private bool ExecuteExpressionOnRow(DataTable dataTable, int row, String expression)
{ {
symbolTable.AddUserSymbols(dataTable); // add symbol names from the data table columns symbolTable.AddUserSymbols(dataTable); // add symbol names from the data table columns
@@ -123,6 +139,13 @@ namespace Axiom.Interpreter
} }
return true; 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) public bool Execute(String expression)
{ {
BinaryReader binaryReader = null; BinaryReader binaryReader = null;
@@ -161,7 +184,7 @@ namespace Axiom.Interpreter
logger.ErrorFormat(LastMessage); logger.ErrorFormat(LastMessage);
return false; 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); assemblerReader = new BinaryReader(parserWriter.BaseStream);
assembler = new Assembler(assemblerReader, symbolTable); assembler = new Assembler(assemblerReader, symbolTable);
assembler.Debug = Trace; 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) public List<String> Disassemble(String expression)
{ {
BinaryReader binaryReader = null; BinaryReader binaryReader = null;
@@ -210,9 +238,10 @@ namespace Axiom.Interpreter
{ {
IsInError=false; IsInError=false;
LastMessage=""; LastMessage="";
SymbolTable localSymbolTable = new SymbolTable();
binaryReader = new BinaryReader(Utility.StreamFromString(expression)); binaryReader = new BinaryReader(Utility.StreamFromString(expression));
binaryWriter = new BinaryWriter(new MemoryStream()); binaryWriter = new BinaryWriter(new MemoryStream());
Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable); Scanner scanner = new Scanner(binaryReader, binaryWriter, localSymbolTable);
scanner.Debug = Trace; scanner.Debug = Trace;
if (!scanner.Analyze()) if (!scanner.Analyze())
{ {
@@ -224,7 +253,7 @@ namespace Axiom.Interpreter
binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin); binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin);
parserReader = new BinaryReader(binaryWriter.BaseStream); parserReader = new BinaryReader(binaryWriter.BaseStream);
parserWriter = new BinaryWriter(new MemoryStream()); parserWriter = new BinaryWriter(new MemoryStream());
Parser parser = new Parser(parserReader, parserWriter, symbolTable); Parser parser = new Parser(parserReader, parserWriter, localSymbolTable);
parser.Debug = Trace; parser.Debug = Trace;
parser.Parse(); parser.Parse();
parseSymbolCount=parser.ParseSymbolsCount; parseSymbolCount=parser.ParseSymbolsCount;
@@ -237,7 +266,7 @@ namespace Axiom.Interpreter
} }
parserWriter.BaseStream.Seek(0, SeekOrigin.Begin); parserWriter.BaseStream.Seek(0, SeekOrigin.Begin);
assemblerReader = new BinaryReader(parserWriter.BaseStream); assemblerReader = new BinaryReader(parserWriter.BaseStream);
assembler = new Assembler(assemblerReader, symbolTable); assembler = new Assembler(assemblerReader, localSymbolTable);
assembler.Debug = Trace; assembler.Debug = Trace;
return assembler.Disassemble(); return assembler.Disassemble();
} }
@@ -412,7 +441,7 @@ namespace Axiom.Interpreter
{ {
logger.Info("********************************************************* O U T P U T ************************************************"); logger.Info("********************************************************* O U T P U T ************************************************");
List<Symbol> list = new List<Symbol>(symbolTable.Values); 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) foreach (Symbol symbol in list)
{ {
logger.Info(String.Format("SYMBOL NAME:'{0}',VALUE:'{1}'", symbol.SymbolName, null == symbol.GenericData ? "<null>" : symbol.GenericData.ToString())); logger.Info(String.Format("SYMBOL NAME:'{0}',VALUE:'{1}'", symbol.SymbolName, null == symbol.GenericData ? "<null>" : symbol.GenericData.ToString()));

View File

@@ -1,204 +1,248 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using log4net; using MarketData;
// FileName : Emitter.cs
// Author : Sean Kessler
namespace Axiom.Interpreter namespace Axiom.Interpreter
{ {
public class Emitter public class Emitter
{ {
private static ILog logger = LogManager.GetLogger(typeof(Emitter));
private bool emitting = true; private bool emitting = true;
private int lastSymbol; private int lastSymbol;
private BinaryReader inputStream; 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; private bool debug = true;
public Emitter(BinaryReader inputStream, BinaryWriter outputStream) public Emitter(BinaryReader inputStream, BinaryWriter outputStream)
{ {
this.inputStream = inputStream; this.inputStream = inputStream;
this.outputStream = outputStream; this.outputStream = outputStream;
this.activeStream = outputStream;
} }
public bool Debug public bool Debug
{ {
get { return debug; } get { return debug; }
set { debug = value; } 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) public void Emit(String literalValue)
{ {
if (!emitting) return; if (!emitting) return;
outputStream.Write(literalValue.Length); activeStream.Write(literalValue.Length);
outputStream.Write(literalValue); activeStream.Write(literalValue);
} }
// ************************************************************************
public void Emit(Scanner.ScanSymbols code) public void Emit(Scanner.ScanSymbols code)
{ {
if (!emitting) return; if (!emitting) return;
outputStream.Write((int)code); activeStream.Write((int)code);
if(Debug)logger.Info(Scanner.SymbolToString(code)); if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Scanner.SymbolToString(code));
} }
public void Emit(Scanner.ScanSymbols code,int value) public void Emit(Scanner.ScanSymbols code,int value)
{ {
if (!emitting) return; if (!emitting) return;
outputStream.Write((int)code); activeStream.Write((int)code);
outputStream.Write(value); activeStream.Write(value);
if(Debug)logger.Info(Scanner.SymbolToString(code)+","+value.ToString()); if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Scanner.SymbolToString(code) + "," + value.ToString());
} }
public void Emit(Scanner.ScanSymbols code,double value) public void Emit(Scanner.ScanSymbols code,double value)
{ {
if (!emitting) return; if (!emitting) return;
outputStream.Write((int)code); activeStream.Write((int)code);
outputStream.Write(value); activeStream.Write(value);
if(Debug)logger.Info(Scanner.SymbolToString(code)+","+value.ToString()); if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Scanner.SymbolToString(code) + "," + value.ToString());
} }
public void Emit(Scanner.ScanSymbols code,String value) public void Emit(Scanner.ScanSymbols code,String value)
{ {
if (!emitting) return; if (!emitting) return;
outputStream.Write((int)code); activeStream.Write((int)code);
outputStream.Write(value); activeStream.Write(value);
if(Debug)logger.Info(Scanner.SymbolToString(code)+","+value.ToString()); if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Scanner.SymbolToString(code) + "," + value.ToString());
} }
// **********************************************************************************************************************************************
public long CodePointer() public long CodePointer()
{ {
return outputStream.BaseStream.Position; return activeStream.BaseStream.Position;
} }
public void Seek(long position)
{ public void Seek(long position)
outputStream.BaseStream.Seek(position, SeekOrigin.Begin); {
activeStream.BaseStream.Seek(position, SeekOrigin.Begin);
} }
public void Emit(Parser.ParserSymbols code) public void Emit(Parser.ParserSymbols code)
{ {
if (!emitting) return; if (!emitting) return;
long positionBefore=outputStream.BaseStream.Position; long positionBefore = activeStream.BaseStream.Position;
outputStream.Write((int)code); activeStream.Write((int)code);
long positionAfter=outputStream.BaseStream.Position; long positionAfter = activeStream.BaseStream.Position;
if(Debug)logger.Info(Parser.SymbolToString(code)+"["+positionBefore+","+positionAfter+"]"); if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Parser.SymbolToString(code) + "[" + positionBefore + "," + positionAfter + "]");
} }
public void Emit(Parser.ParserSymbols code,Object value) public void Emit(Parser.ParserSymbols code,Object value)
{ {
if (!emitting) return; if (!emitting) return;
long positionBefore=outputStream.BaseStream.Position; long positionBefore = activeStream.BaseStream.Position;
outputStream.Write((int)code); activeStream.Write((int)code);
Type type = value.GetType(); Type type = value.GetType();
outputStream.Write(type.ToString()); activeStream.Write(type.ToString());
outputStream.Write(value.ToString()); activeStream.Write(value.ToString());
long positionAfter=outputStream.BaseStream.Position; long positionAfter = activeStream.BaseStream.Position;
if(Debug)logger.Info(Parser.SymbolToString(code)+","+type.ToString()+","+value.ToString()+"["+positionBefore+","+positionAfter+"]"); 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) public void Emit(Parser.ParserSymbols code,Object value,int intValue)
{ {
if (!emitting) return; if (!emitting) return;
long positionBefore=outputStream.BaseStream.Position; long positionBefore = activeStream.BaseStream.Position;
outputStream.Write((int)code); activeStream.Write((int)code);
Type type = value.GetType(); Type type = value.GetType();
outputStream.Write(type.ToString()); activeStream.Write(type.ToString());
outputStream.Write(value.ToString()); activeStream.Write(value.ToString());
outputStream.Write(intValue); activeStream.Write(intValue);
long positionAfter=outputStream.BaseStream.Position; long positionAfter = activeStream.BaseStream.Position;
if(Debug)logger.Info(Parser.SymbolToString(code)+","+type.ToString()+","+value.ToString()+","+intValue+"["+positionBefore+","+positionAfter+"]"); if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Parser.SymbolToString(code) + "," + type.ToString() + "," + value.ToString() + "," + intValue + "[" + positionBefore + "," + positionAfter + "]");
} }
public void Emit(Parser.ParserSymbols code,long value) public void Emit(Parser.ParserSymbols code,long value)
{ {
if (!emitting) return; if (!emitting) return;
long positionBefore=outputStream.BaseStream.Position; long positionBefore = activeStream.BaseStream.Position;
outputStream.Write((int)code); activeStream.Write((int)code);
outputStream.Write(value); activeStream.Write(value);
long positionAfter=outputStream.BaseStream.Position; long positionAfter = activeStream.BaseStream.Position;
if(Debug)logger.Info(Parser.SymbolToString(code)+","+value.ToString()+","+value.ToString()+"["+positionBefore+","+positionAfter+"]"); if (Debug) MDTrace.WriteLine(LogLevel.DEBUG, Parser.SymbolToString(code) + "," + value.ToString() + "," + value.ToString() + "[" + positionBefore + "," + positionAfter + "]");
} }
public void EmitAsNull(Parser.ParserSymbols code) public void EmitAsNull(Parser.ParserSymbols code)
{ {
if (!emitting) return; if (!emitting) return;
long positionBefore=outputStream.BaseStream.Position; long positionBefore = activeStream.BaseStream.Position;
outputStream.Write((int)code); activeStream.Write((int)code);
Type type = typeof(System.Nullable); //value.GetType(); Type type = typeof(System.Nullable);
outputStream.Write(type.ToString()); activeStream.Write(type.ToString());
outputStream.Write("null".ToString()); activeStream.Write("null".ToString());
long positionAfter=outputStream.BaseStream.Position; long positionAfter = activeStream.BaseStream.Position;
if(Debug)logger.Info(Parser.SymbolToString(code)+","+type.ToString()+","+"null".ToString()+"["+positionBefore+","+positionAfter+"]"); 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; if (!emitting) return;
outputStream.Write(code); activeStream.Write(code);
outputStream.Write(op); activeStream.Write(op);
} }
public void Emit(int identifier) public void Emit(int identifier)
{ {
if (!emitting) return; if (!emitting) return;
outputStream.Write(identifier); activeStream.Write(identifier);
} }
public void Emit(byte value) public void Emit(byte value)
{ {
if (!emitting) return; 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() public int Read()
{ {
lastSymbol = inputStream.Read(); lastSymbol = inputStream.Read();
return lastSymbol; return lastSymbol;
} }
public int Read(ref String literal) public int Read(ref String literal)
{ {
literal=inputStream.ReadString(); literal = inputStream.ReadString();
return 0; return 0;
} }
public int Read(ref byte value) public int Read(ref byte value)
{ {
try { value = inputStream.ReadByte(); return 0; } try { value = inputStream.ReadByte(); return 0; }
catch (EndOfStreamException) { return 0xFFFF; } catch (EndOfStreamException) { return 0xFFFF; }
} }
public int Read(ref int value) public int Read(ref int value)
{ {
try { value = inputStream.ReadInt32(); return 0; } try { value = inputStream.ReadInt32(); return 0; }
catch (EndOfStreamException) { return 0xFFFF; } catch (EndOfStreamException) { return 0xFFFF; }
} }
public int Read(ref double value) public int Read(ref double value)
{ {
try { value = inputStream.ReadDouble(); return 0; } try { value = inputStream.ReadDouble(); return 0; }
catch (EndOfStreamException) { return 0xFFFF; } catch (EndOfStreamException) { return 0xFFFF; }
} }
public bool Emitting public bool Emitting
{ {
get get { return emitting; }
{ set { emitting = value; }
return emitting;
}
set
{
emitting = value;
}
} }
} }
} }

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using System.Runtime.Remoting.Messaging;
// FileName : Parser.cs // FileName : Parser.cs
// Author : Sean Kessler // Author : Sean Kessler
@@ -34,7 +35,7 @@ namespace Axiom.Interpreter
private String stringValue; 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 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<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) public Parser(BinaryReader binaryReader, BinaryWriter binaryWriter, SymbolTable symbolTable)
: base(binaryReader, binaryWriter) : base(binaryReader, binaryWriter)
@@ -135,11 +136,16 @@ namespace Axiom.Interpreter
BreakStatement(); BreakStatement();
StatementNumber++; StatementNumber++;
} }
else if (Scanner.ScanSymbols.while1.Equals(currentSymbolType)) else if (Scanner.ScanSymbols.while1.Equals(currentSymbolType))
{ {
WhileStatement(); WhileStatement();
StatementNumber++; StatementNumber++;
} }
else if (Scanner.ScanSymbols.for1.Equals(currentSymbolType))
{
ForStatement();
StatementNumber++;
}
else if (SymbolIn(termSymbols)) else if (SymbolIn(termSymbols))
{ {
Term(); Term();
@@ -157,6 +163,7 @@ namespace Axiom.Interpreter
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1)); RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1));
return; return;
} }
public void DeclarationStatement() public void DeclarationStatement()
{ {
bool moreDeclarations = true; bool moreDeclarations = true;
@@ -178,21 +185,24 @@ namespace Axiom.Interpreter
} }
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
} }
public void DirectiveClearModified() public void DirectiveClearModified()
{ {
Emit(Parser.ParserSymbols.directive_clear_modified2); Emit(Parser.ParserSymbols.directive_clear_modified2);
Expect(Scanner.ScanSymbols.directive_clear_modified1); Expect(Scanner.ScanSymbols.directive_clear_modified1);
} }
public void ParseLiteral() public void ParseLiteral()
{ {
Emit(Parser.ParserSymbols.push2, stringValue); Emit(Parser.ParserSymbols.push2, stringValue);
Expect(Scanner.ScanSymbols.literal1); Expect(Scanner.ScanSymbols.literal1);
} }
public void BreakStatement() 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) if(breakStack.Count>0)
{ {
@@ -205,6 +215,267 @@ namespace Axiom.Interpreter
breakStack.Push(CodePointer()); breakStack.Push(CodePointer());
Expect(Scanner.ScanSymbols.break1); 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> /// <summary>
/// WhileStatement Parses WhileStatement. /// WhileStatement Parses WhileStatement.
///WHILE ///WHILE
@@ -221,36 +492,42 @@ namespace Axiom.Interpreter
long codePointerL2; long codePointerL2;
long codePointerTerminalAddress; 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(expressionSymbols);
InsertSymbols(directiveSymbols); InsertSymbols(directiveSymbols);
Expect(Scanner.ScanSymbols.while1); Expect(Scanner.ScanSymbols.while1);
Expect(Scanner.ScanSymbols.leftparen1); Expect(Scanner.ScanSymbols.leftparen1);
RemoveSymbols(expressionSymbols); RemoveSymbols(expressionSymbols);
RemoveSymbols(directiveSymbols); RemoveSymbols(directiveSymbols);
if (IsInError){whileStack.Pop(); return;} if (IsInError){loopStack.Pop(); return;}
codePointerL1 = CodePointer(); // L1: codePointerL1 = CodePointer(); // L1:
DoBForWhile(); // B DoBForWhile(); // B
if(IsInError){whileStack.Pop(); return;} if(IsInError){loopStack.Pop(); return;}
codePointerFalseInstructionAddress = CodePointer(); // Record the location of the DEFADDR2 instruction. codePointerFalseInstructionAddress = CodePointer(); // Record the location of the DEFADDR2 instruction.
Emit(Parser.ParserSymbols.defaddr2,0L); // Write DEFADDR2,0L. This will be jump to condition:false Emit(Parser.ParserSymbols.defaddr2,0L); // Write DEFADDR2,0L. This will be jump to condition:false
DoSForWhile(); // S DoSForWhile(); // S
if(IsInError){whileStack.Pop(); return;} if(IsInError){loopStack.Pop(); return;}
Emit(Parser.ParserSymbols.goto2,codePointerL1); // Goto(L1) Emit(Parser.ParserSymbols.goto2,codePointerL1); // Goto(L1)
codePointerL2=CodePointer(); // L2: codePointerL2=CodePointer(); // L2:
Emit(Parser.ParserSymbols.noop2); // Don't write any instructions past this point Emit(Parser.ParserSymbols.noop2); // Don't write any instructions past this point
codePointerTerminalAddress=CodePointer(); // Record code pointer before seeking codePointerTerminalAddress=CodePointer(); // Record code pointer before seeking
Seek(codePointerFalseInstructionAddress); // Seek to DEFADDR2 instruction Seek(codePointerFalseInstructionAddress); // Seek to DEFADDR2 instruction
Emit(Parser.ParserSymbols.defaddr2,codePointerL2); // Write DEFADDR2, L2 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); 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) public void HandleBreak(long codePointerL2)
{ {
if(0==breakStack.Count)return; if(0==breakStack.Count)return;
Seek(breakStack.Pop()); Seek(breakStack.Pop());
Emit(Parser.ParserSymbols.goto2,codePointerL2); Emit(Parser.ParserSymbols.goto2,codePointerL2);
} }
/// <summary> /// <summary>
/// B Section for While. /// B Section for While.
@@ -1499,6 +1776,12 @@ namespace Axiom.Interpreter
else SyntaxError(symbol); else SyntaxError(symbol);
SyntaxCheck(); SyntaxCheck();
} }
public long SymbolCount()
{
return parseSymbols.Count;
}
public void InsertSymbols(ParseSymbols groupSymbols) public void InsertSymbols(ParseSymbols groupSymbols)
{ {
parseSymbols.InsertSymbols(groupSymbols); parseSymbols.InsertSymbols(groupSymbols);
@@ -1600,6 +1883,7 @@ namespace Axiom.Interpreter
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.literal1)); statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.literal1));
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.if1)); statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.if1));
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.while1)); 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.declare1));
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.break1)); statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.break1));
} }

View File

@@ -9,7 +9,11 @@ namespace Axiom.Interpreter
{ {
public class Scanner : Emitter 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 enum WhiteSpace{spacechar=32,tabchar=9};
private int character; private int character;
private StringBuilder word; private StringBuilder word;
@@ -409,6 +413,8 @@ namespace Axiom.Interpreter
return "if"; return "if";
case Scanner.ScanSymbols.while1 : case Scanner.ScanSymbols.while1 :
return "while"; return "while";
case Scanner.ScanSymbols.for1 :
return "for";
case Scanner.ScanSymbols.then1 : case Scanner.ScanSymbols.then1 :
return "then"; return "then";
case Scanner.ScanSymbols.else1 : case Scanner.ScanSymbols.else1 :
@@ -523,6 +529,8 @@ namespace Axiom.Interpreter
return "if1"; return "if1";
case Scanner.ScanSymbols.while1 : case Scanner.ScanSymbols.while1 :
return "while1"; return "while1";
case Scanner.ScanSymbols.for1 :
return "for1";
case Scanner.ScanSymbols.then1 : case Scanner.ScanSymbols.then1 :
return "then1"; return "then1";
case Scanner.ScanSymbols.else1 : case Scanner.ScanSymbols.else1 :

View File

@@ -140,6 +140,7 @@ namespace Axiom.Interpreter
Add("if",new Symbol("if",Scanner.ScanSymbols.if1,Symbol.SymbolType.KeywordSymbol)); Add("if",new Symbol("if",Scanner.ScanSymbols.if1,Symbol.SymbolType.KeywordSymbol));
Add("break",new Symbol("break",Scanner.ScanSymbols.break1,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("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("then", new Symbol("then", Scanner.ScanSymbols.then1, Symbol.SymbolType.KeywordSymbol));
Add("else", new Symbol("else", Scanner.ScanSymbols.else1, 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)); Add("and", new Symbol("and", Scanner.ScanSymbols.andand1, Symbol.SymbolType.KeywordSymbol));

View File

@@ -8,4 +8,4 @@
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </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>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup> </startup>
</configuration> </configuration>

View File

@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AxiomConsole</RootNamespace> <RootNamespace>AxiomConsole</RootNamespace>
<AssemblyName>AxiomConsole</AssemblyName> <AssemblyName>AxiomConsole</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>

View File

@@ -22,52 +22,61 @@ namespace AxiomConsole
// IF(A==1)THEN BREAK; // IF(A==1)THEN BREAK;
// A=A+1; // A=A+1;
// }"; // }";
String expression=@" //String expression = @"
A=1; // J=1;
B=1; // FOR(I=1;I<10;I=I+1)
C=1; // {
D=1; // J=J+10;
WHILE(A<10) // break;
{ // }
WHILE(B<10) // ";
//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; BREAK;
TOTAL=TOTAL+1
} }
BREAK;
} }
BREAK; ";
}";
CodeRunner codeRunner = new CodeRunner(); CodeRunner codeRunner = new CodeRunner();
codeRunner.Trace=true;
//if (!codeRunner.Execute(expression)) //if (!codeRunner.Execute(expression))
//{ //{
// Console.WriteLine("CodeRunner Failed with {0}", codeRunner.LastMessage); // Console.WriteLine("CodeRunner Failed with {0}", codeRunner.LastMessage);
// Console.Read(); // Console.Read();
//} //}
List<String> disassembly=codeRunner.Disassemble(expression);
if(codeRunner.IsInError) List<String> disassembly = codeRunner.Disassemble(expression);
{ if (codeRunner.IsInError)
Console.WriteLine("CodeRunner Failed with {0}",codeRunner.LastMessage); {
} Console.WriteLine("CodeRunner Failed with {0}", codeRunner.LastMessage);
else } else
{ {
Console.WriteLine(expression); Console.WriteLine(expression);
foreach(String line in disassembly) foreach (String line in disassembly)
{ {
Console.WriteLine(line); Console.WriteLine(line);
} }
} }
Console.Read(); Console.Read();
} }
} }

View File

@@ -1,4 +1,4 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<configuration> <configuration>
<appSettings> <appSettings>
<add key="market_data" value="Database=market_data;Datasource=localhost;Username=root;Password=dbas"/> <add key="market_data" value="Database=market_data;Datasource=localhost;Username=root;Password=dbas"/>
@@ -6,6 +6,6 @@
</appSettings> </appSettings>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup> </startup>
</configuration> </configuration>

View File

@@ -176,6 +176,71 @@ namespace AxiomUnitTestProject
Assert.IsTrue(codeRunner.GetValue<double>("B").Equals(5)); 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] [TestMethod]
public void WhileStatementVariant4() public void WhileStatementVariant4()
{ {

View File

@@ -8,7 +8,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AxiomUnitTestProjectr</RootNamespace> <RootNamespace>AxiomUnitTestProjectr</RootNamespace>
<AssemblyName>AxiomUnitTestProjectr</AssemblyName> <AssemblyName>AxiomUnitTestProjectr</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
@@ -62,7 +62,7 @@
<Compile Include="TestData.cs" /> <Compile Include="TestData.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Axiom.Core\Axiom.Core.csproj"> <ProjectReference Include="..\Axiom.Core\Axiom.Core.csproj">
<Project>{f0f0f2b4-bb86-49b5-ba93-2642637033d6}</Project> <Project>{f0f0f2b4-bb86-49b5-ba93-2642637033d6}</Project>
<Name>Axiom.Core</Name> <Name>Axiom.Core</Name>
</ProjectReference> </ProjectReference>

View File

@@ -1,9 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.21005.1 VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AxiomUnitTestProject", "AxiomUnitTestProjectr\AxiomUnitTestProject.csproj", "{E2FC10FA-2B8A-4CEB-B7C6-960FA6A3AC6F}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AxiomUnitTestProject", "AxiomUnitTestProject.csproj", "{E2FC10FA-2B8A-4CEB-B7C6-960FA6A3AC6F}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Axiom.Core", "..\Axiom.Core\Axiom.Core.csproj", "{F0F0F2B4-BB86-49B5-BA93-2642637033D6}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Axiom.Core", "..\Axiom.Core\Axiom.Core.csproj", "{F0F0F2B4-BB86-49B5-BA93-2642637033D6}"
EndProject EndProject