commit 320bbfa7ace69c1db2761558ae8179d30d807961 Author: Sean Kessler Date: Thu Feb 22 15:13:49 2024 -0500 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e759b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,330 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ diff --git a/Axiom.Core/Axiom.Core.csproj b/Axiom.Core/Axiom.Core.csproj new file mode 100644 index 0000000..bcd3afe --- /dev/null +++ b/Axiom.Core/Axiom.Core.csproj @@ -0,0 +1,86 @@ + + + + + Debug + AnyCPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6} + Library + Axiom.Core + Axiom.Core + v4.6.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll + + + ..\References\MarketDataLib.dll + + + + + + + + + + + + 4.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Axiom.Core/Interpreter/Assembler.cs b/Axiom.Core/Interpreter/Assembler.cs new file mode 100644 index 0000000..989d9de --- /dev/null +++ b/Axiom.Core/Interpreter/Assembler.cs @@ -0,0 +1,1118 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Configuration; +using log4net; +using System.Globalization; +using Axiom.Utils; + +// FileName : Assembler.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class Assembler + { + private static ILog logger = LogManager.GetLogger(typeof(Assembler)); + private BinaryReader binaryReader; + private SymbolTable symbolTable; + private CodeStack codeStack = new CodeStack(); + private bool isInError=false; + private String lastMessage; + + public Assembler(BinaryReader binaryReader, SymbolTable symbolTable) + { + this.binaryReader=binaryReader; + this.symbolTable = symbolTable; + this.isInError=false; + } + public bool IsInError + { + get{return isInError;} + } + public String LastMessage + { + get{return lastMessage;} + } + public bool Debug {get;set;} + public void Dispose() + { + } +// ****************************************************************************************************************************************************************************************************************************** +// ****************************************************************************************************** M A I N A S S E M B L E R S T A G E S ****************************************************************************** +// ****************************************************************************************************************************************************************************************************************************** +// main code assembler + public bool Assemble() + { + + try + { + isInError=false; + Parser.ParserSymbols symbol = Parser.ParserSymbols.undefined2; + while (symbol != Parser.ParserSymbols.codeend2) + { + if(isInError)break; + long position = binaryReader.BaseStream.Position; + symbol = (Parser.ParserSymbols)binaryReader.ReadInt32(); + switch (symbol) + { + case Parser.ParserSymbols.directive_clear_modified2 : + DirectiveClearModified(); + break; + case Parser.ParserSymbols.declare2 : + Declare(); + break; + case Parser.ParserSymbols.oror2 : + Or(); + break; + case Parser.ParserSymbols.andand2 : + AndAnd(); + break; + case Parser.ParserSymbols.less2 : + Less(); + break; + case Parser.ParserSymbols.lessequal2 : + LessEqual(); + break; + case Parser.ParserSymbols.greater2 : + Greater(); + break; + case Parser.ParserSymbols.greaterequal2 : + GreaterEqual(); + break; + case Parser.ParserSymbols.equalequal2 : + EqualEqual(); + break; + case Parser.ParserSymbols.notequal2 : + NotEqual(); + break; + case Parser.ParserSymbols.noop2 : + Nop(); + break; + case Parser.ParserSymbols.goto2 : + Goto(); + break; + case Parser.ParserSymbols.defaddr2 : + Defaddr(); + break; + case Parser.ParserSymbols.divide2 : // when we add we pop 2 items, add them and then push the result on the stack + Divide(); + break; + case Parser.ParserSymbols.multiply2 : // when we add we pop 2 items, add them and then push the result on the stack + Multiply(); + break; + case Parser.ParserSymbols.add2 : // when we add we pop 2 items, add them and then push the result on the stack + Add(); + break; + case Parser.ParserSymbols.subtract2 : + Subtract(); + break; + case Parser.ParserSymbols.assign2 : + Assign(); + break; + case Parser.ParserSymbols.variableaccess2 : + VariableAccess(); + break; + case Parser.ParserSymbols.call2 : + Call(); + break; + case Parser.ParserSymbols.push2 : + Push(); + break; + case Parser.ParserSymbols.negate2 : + Negate(); + break; + case Parser.ParserSymbols.not2 : + Not(); + break; + case Parser.ParserSymbols.codeend2 : + break; + default : + logger.Info(String.Format("No action for symbol {0}",Parser.SymbolToString(symbol))); + break; + } + } + return !isInError; + } + catch(Exception exception) + { + logger.ErrorFormat("Exception during Assembly:{0}",exception); + return false; + } + } +// the disassembler + public List Disassemble() + { + List disassembly=new List(); + + String variableType = null; + String variableName = null; + isInError=false; + Parser.ParserSymbols symbol = Parser.ParserSymbols.undefined2; + binaryReader.BaseStream.Seek(0, SeekOrigin.Begin); + long position=binaryReader.BaseStream.Position; + long finalPosition = 0; + long instructionLength=0; + + disassembly.Add("[position:instructionlength] S:Symbol V:Value VT:VariableType VN:VariableName VV:VariableValue FT:FunctionType FN:FunctionName STK:Stack Parameter Count"); + + while (symbol != Parser.ParserSymbols.codeend2) + { + long value = 0L; + position = binaryReader.BaseStream.Position; + try + { + symbol = (Parser.ParserSymbols)binaryReader.ReadInt32(); + } + catch (Exception) + { + break; + } + + switch (symbol) + { + case Parser.ParserSymbols.defaddr2 : + value = binaryReader.ReadInt64(); + instructionLength=binaryReader.BaseStream.Position-position; + disassembly.Add(String.Format("{0} {1} {2}",Format(position,instructionLength),Parser.SymbolToString(symbol),value)); + break; + case Parser.ParserSymbols.goto2 : + value = binaryReader.ReadInt64(); + instructionLength=binaryReader.BaseStream.Position-position; + disassembly.Add(String.Format("{0} {1} {2}",Format(position,instructionLength),Parser.SymbolToString(symbol),value)); + break; + case Parser.ParserSymbols.declare2 : + variableType = binaryReader.ReadString(); + variableName = binaryReader.ReadString(); + instructionLength=binaryReader.BaseStream.Position-position; + disassembly.Add(String.Format("{0} {1} {2} {3}",Format(position,instructionLength),Parser.SymbolToString(symbol),variableType,variableName)); + break; + case Parser.ParserSymbols.directive_clear_modified2 : + case Parser.ParserSymbols.oror2 : + case Parser.ParserSymbols.andand2 : + case Parser.ParserSymbols.less2 : + case Parser.ParserSymbols.lessequal2 : + case Parser.ParserSymbols.greater2 : + case Parser.ParserSymbols.greaterequal2 : + case Parser.ParserSymbols.equalequal2 : + case Parser.ParserSymbols.notequal2 : + case Parser.ParserSymbols.noop2 : + case Parser.ParserSymbols.divide2 : // when we div we pop 2 items, div them and then push the result on the stack + case Parser.ParserSymbols.multiply2 : // when we mul we pop 2 items, mul them and then push the result on the stack + case Parser.ParserSymbols.add2 : // when we add we pop 2 items, add them and then push the result on the stack + case Parser.ParserSymbols.subtract2 : + case Parser.ParserSymbols.assign2 : + case Parser.ParserSymbols.negate2 : + case Parser.ParserSymbols.not2 : + instructionLength=binaryReader.BaseStream.Position-position; + disassembly.Add(String.Format("{0} {1}",Format(position,instructionLength),Parser.SymbolToString(symbol))); + break; + case Parser.ParserSymbols.codeend2 : + instructionLength=binaryReader.BaseStream.Position-position; + finalPosition = binaryReader.BaseStream.Position; + disassembly.Add(String.Format("{0} {1}",Format(position,instructionLength),Parser.SymbolToString(symbol))); + break; + case Parser.ParserSymbols.variableaccess2 : + variableType = binaryReader.ReadString(); + variableName = binaryReader.ReadString(); + instructionLength=binaryReader.BaseStream.Position-position; + disassembly.Add(String.Format("{0} {1} {2} {3}",Format(position,instructionLength),Parser.SymbolToString(symbol),variableType,variableName)); + break; + case Parser.ParserSymbols.call2 : + String functionNameType = binaryReader.ReadString(); + String functionName = binaryReader.ReadString(); + int stackParameterCount = binaryReader.ReadInt32(); + instructionLength=binaryReader.BaseStream.Position-position; + disassembly.Add(String.Format("{0} {1} {2} {3} stack[{4}]",Format(position,instructionLength),Parser.SymbolToString(symbol),functionNameType,functionName,stackParameterCount)); + break; + case Parser.ParserSymbols.push2 : + variableType = binaryReader.ReadString(); + String variableValue = binaryReader.ReadString(); + instructionLength=binaryReader.BaseStream.Position-position; + disassembly.Add(String.Format("{0} {1} {2} {3}",Format(position,instructionLength),Parser.SymbolToString(symbol),variableType,variableValue)); + break; + default : + break; + } + } + binaryReader.BaseStream.Seek(0, SeekOrigin.Begin); + disassembly.Add(String.Format("[{0}:0]",finalPosition)); + return disassembly; + } + private String Format(long position,long length) + { + return String.Format("[{0}:{1}]",Utility.Pad(position.ToString(),'0',6),Utility.Pad(length.ToString(),'0',6)); + } + public void DisassembleToLog() + { + List disassembly=Disassemble(); + foreach(String line in disassembly) + { + logger.Info(line); + } + } +// Fixup is used for combining multiple assembly streams. It resolves jump targets across each of these streams by offsetting the target address destinations by the relative code lengths of the streams. + public void Fixup(long fixupAddress) + { + Dictionary offsets = new Dictionary(); + String variableType = null; + if(isInError)return; + Parser.ParserSymbols symbol = Parser.ParserSymbols.undefined2; + binaryReader.BaseStream.Seek(0, SeekOrigin.Begin); + while (symbol != Parser.ParserSymbols.codeend2) + { + long offset = 0L; + long value = 0L; + long position = binaryReader.BaseStream.Position; + try { symbol = (Parser.ParserSymbols)binaryReader.ReadInt32(); } + catch (Exception) { break; } + switch (symbol) + { + case Parser.ParserSymbols.defaddr2 : + offset = binaryReader.BaseStream.Position; + value = binaryReader.ReadInt64(); + offsets.Add(offset,value); + break; + case Parser.ParserSymbols.goto2 : + offset = binaryReader.BaseStream.Position; + value = binaryReader.ReadInt64(); + offsets.Add(offset,value); + break; + case Parser.ParserSymbols.directive_clear_modified2 : + case Parser.ParserSymbols.oror2 : + case Parser.ParserSymbols.andand2 : + case Parser.ParserSymbols.less2 : + case Parser.ParserSymbols.lessequal2 : + case Parser.ParserSymbols.greater2 : + case Parser.ParserSymbols.greaterequal2 : + case Parser.ParserSymbols.equalequal2 : + case Parser.ParserSymbols.notequal2 : + case Parser.ParserSymbols.noop2 : + case Parser.ParserSymbols.divide2 : // when we add we pop 2 items, add them and then push the result on the stack + case Parser.ParserSymbols.multiply2 : // when we add we pop 2 items, add them and then push the result on the stack + case Parser.ParserSymbols.add2 : // when we add we pop 2 items, add them and then push the result on the stack + case Parser.ParserSymbols.subtract2 : + case Parser.ParserSymbols.assign2 : + case Parser.ParserSymbols.negate2 : + case Parser.ParserSymbols.declare2 : + case Parser.ParserSymbols.not2 : + break; + case Parser.ParserSymbols.variableaccess2 : + variableType = binaryReader.ReadString(); + String variableName = binaryReader.ReadString(); + break; + case Parser.ParserSymbols.call2 : + String functionNameType = binaryReader.ReadString(); + String functionName = binaryReader.ReadString(); + int stackParameterCount = binaryReader.ReadInt32(); + break; + case Parser.ParserSymbols.push2 : + variableType = binaryReader.ReadString(); + String variableValue = binaryReader.ReadString(); + break; + case Parser.ParserSymbols.codeend2 : + break; + default : + break; + } + } + binaryReader.BaseStream.Seek(0, SeekOrigin.Begin); + BinaryWriter binaryWriter = new BinaryWriter(binaryReader.BaseStream); + List addressList = new List(offsets.Keys); + foreach (long address in addressList) + { + binaryWriter.Seek((int)address, SeekOrigin.Begin); + long value=offsets[address]; + binaryWriter.Write((long)(value+fixupAddress)); + binaryWriter.Flush(); + } + binaryReader.BaseStream.Seek(0, SeekOrigin.Begin); + } +// ****************************************************************************************************************************************************************************************************************************** +// ****************************************************************************************************** D E C L A R A T I O N ************************************************************************************************ +// ****************************************************************************************************************************************************************************************************************************** + private void Declare() + { + if(isInError)return; + String variableType = binaryReader.ReadString(); + String variableName = binaryReader.ReadString(); + if(symbolTable.ContainsKey(variableName)) + { + isInError = true; + lastMessage=String.Format("Runtime Error: The variable '{0}' has already been declared.",variableName); + return; + } + Symbol symbol = new Symbol(variableName, Scanner.ScanSymbols.variable1, Symbol.SymbolType.UserDynamicSymbol); + symbol.GenericData = new GenericData(); + symbol.GenericData.SetNull(variableType); + symbolTable.Add(variableName, symbol); + } +// ****************************************************************************************************************************************************************************************************************************** +// ************************************************************************************************************* C A L L S ***************************************************************************************************** +// ****************************************************************************************************************************************************************************************************************************** + private void Call() + { + try + { + if(isInError)return; + String functionNameType = binaryReader.ReadString(); + String functionName = binaryReader.ReadString(); + int stackParameterCount = binaryReader.ReadInt32(); + StackElement[] stackElements = new StackElement[stackParameterCount]; + for (int index = stackElements.Length - 1; index >= 0; index--) + { + stackElements[index] = codeStack.Pop(); + } + switch (functionName) + { + case "abs": + PerformABS(stackElements); + break; + case "pow": + PerformPOW(stackElements); + break; + case "sqrt": + PerformSQRT(stackElements); + break; + case "convert" : + PerformConvert(stackElements); + break; + case "in" : + PerformIn(stackElements); + break; + case "isnull" : + PerformIsNull(stackElements); + break; + case "like" : + PerformLike(stackElements); + break; + case "trim" : + PerformTrim(stackElements); + break; + case "upper" : + PerformUpper(stackElements); + break; + case "lower" : + PerformLower(stackElements); + break; + case "substring" : + PerformSubstring(stackElements); + break; + case "getprice" : + PerformGetPrice(stackElements); + break; + default: + break; + } + } + finally + { + } + } +// ****************************************************************************************************************************************************************************************************************************** +// **************************************************************************************************** O P E R A T I O N S ***************************************************************************************************** +// ****************************************************************************************************************************************************************************************************************************** + private void Nop() + { + } + /// + /// Goto reads a stream position from the input stream and seeks to that location and code execution will continue at that location. + /// + private void Goto() + { + try + { + if(isInError)return; + long position = binaryReader.ReadInt64(); + binaryReader.BaseStream.Seek(position, SeekOrigin.Begin); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + /// + /// DefAddr reads a stream position from the input stream and pops a boolean value from the stack which is the result of a previous logical operation. + /// If the boolean value is false the stream will seek to position and code execution will continue at that location. + /// + private void Defaddr() + { + try + { + if(isInError)return; + long position = binaryReader.ReadInt64(); + StackElement stackElement1 = codeStack.Pop(); + bool result = stackElement1.Value.Get(); + if (!result) binaryReader.BaseStream.Seek(position, SeekOrigin.Begin); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Or() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + if(null==genericData1)genericData1=new GenericData(); + element.Value = genericData1.Or(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void AndAnd() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + if(null==genericData1)genericData1=new GenericData(); + element.Value = genericData1.And(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void LessEqual() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + if(null==genericData1)genericData1=new GenericData(); + element.Value = genericData1.LessEqual(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Greater() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + if(null==genericData1)genericData1=new GenericData(); + element.Value = genericData1.Greater(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void GreaterEqual() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + element.Value = genericData1.GreaterEqual(genericData2); + if(null==genericData1)genericData1=new GenericData(); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void EqualEqual() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + if(null==genericData1)genericData1=new GenericData(); + element.Value = genericData1.EqualEqual(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void NotEqual() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + if(null==genericData1)genericData1=new GenericData(); + element.Value = genericData1.NotEqual(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Less() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + if(null==genericData1)genericData1=new GenericData(); + element.Value = genericData1.Less(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Negate() + { + try + { + if(isInError)return; + StackElement stackElement = codeStack.Pop(); + StackElement element = new StackElement(); + if (null != stackElement.Symbol) element.Value = stackElement.Symbol.GenericData.Negate(); + else element.Value = stackElement.Value.Negate(); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Not() + { + try + { + if(isInError)return; + StackElement stackElement = codeStack.Pop(); + StackElement element = new StackElement(); + if (null != stackElement.Symbol) element.Value = stackElement.Symbol.GenericData.Not(); + else element.Value = stackElement.Value.Not(); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Add() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + element.Value = genericData1.Add(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Multiply() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + element.Value = genericData2.Multiply(genericData1); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Divide() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + element.Value = genericData1.Divide(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + private void Subtract() + { + try + { + if(isInError)return; + StackElement stackElement2 = codeStack.Pop(); + StackElement stackElement1 = codeStack.Pop(); + StackElement element = new StackElement(); + GenericData genericData1 = null == stackElement1.Symbol ? stackElement1.Value : stackElement1.Symbol.GenericData; + GenericData genericData2 = null == stackElement2.Symbol ? stackElement2.Value : stackElement2.Symbol.GenericData; + element.Value = genericData1.Subtract(genericData2); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void DirectiveClearModified() + { + try + { + if(isInError)return; + symbolTable.ClearModified(); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void Assign() + { + try + { + if(isInError)return; + StackElement sourceElement = codeStack.Pop(); + StackElement destinationElement = codeStack.Pop(); + GenericData sourceData = (null == sourceElement.Symbol ? sourceElement.Value : sourceElement.Symbol.GenericData); + if (null != destinationElement.Symbol) + { + destinationElement.Symbol.GenericData = GenericData.Clone(sourceData); + destinationElement.Symbol.IsModified=true; + } + else + { + destinationElement.Value = new GenericData(); + destinationElement.Value.Data = GenericData.Clone(sourceData); + destinationElement.Value.IsModified=true; + } + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + logger.ErrorFormat("Exception:{0}",exception); + } + } + public void VariableAccess() + { + try + { + if(isInError)return; + String variableType = binaryReader.ReadString(); + String variableName = binaryReader.ReadString(); + Symbol symbol = null; + if (!symbolTable.ContainsKey(variableName)) // if variable name does not exist then create it on the fly + { + symbol = new Symbol(); + GenericData genericData = new GenericData(); + symbol.SymbolName = variableName; + symbol.GenericData = genericData; + symbol.GenericData.SetNull(); + symbolTable.Add(variableName, symbol); + } + symbol = symbolTable[variableName]; + StackElement stackElement = new StackElement(); + stackElement.Symbol = symbol; + codeStack.Push(stackElement); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void Push() + { + try + { + if(isInError)return; + String variableType = binaryReader.ReadString(); + String variableValue = binaryReader.ReadString(); + StackElement stackElement = new StackElement(); + stackElement.Value = new GenericData(); + if(variableType.Equals("System.Nullable"))stackElement.Value.SetData(null, variableType); + else stackElement.Value.SetData(variableValue, variableType); + codeStack.Push(stackElement); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } +// ****************************************************************************************************************************************************************************************************************************** +// ********************************************************************************************************** F U N C T I O N S ************************************************************************************************* +// ****************************************************************************************************************************************************************************************************************************** + public void PerformABS(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (1 != stackElements.Length) return; + StackElement element = new StackElement(); + GenericData param1 = null; + if (null == stackElements[0].Value) param1 = stackElements[0].Symbol.GenericData; + else param1 = stackElements[0].Value; + element.Value = param1.Abs(); + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformPOW(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (2 != stackElements.Length) return; + StackElement element = new StackElement(); + GenericData param1 = null; + GenericData param2 = null; + + if (null == stackElements[0].Value) param1 = stackElements[0].Symbol.GenericData; + else param1 = stackElements[0].Value; + if (null == stackElements[1].Value) param2 = stackElements[1].Symbol.GenericData; + else param2 = stackElements[1].Value; + GenericData genericData = new GenericData(); + genericData.SetData(Math.Pow(param1.Get(), param2.Get())); + element.Value = genericData; + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformSQRT(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (1 != stackElements.Length) return; + StackElement element = new StackElement(); + GenericData param1 = null; + + if (null == stackElements[0].Value) param1 = stackElements[0].Symbol.GenericData; + else param1 = stackElements[0].Value; + GenericData genericData = new GenericData(); + genericData.SetData(Math.Sqrt(param1.Get())); + element.Value = genericData; + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformConvert(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (2 != stackElements.Length) return; + StackElement element = new StackElement(); + GenericData genericData = null; + GenericData param1 = null; + GenericData param2 = null; + + if (null == stackElements[0].Value) param1 = stackElements[0].Symbol.GenericData; + else param1 = stackElements[0].Value; + if (null == stackElements[1].Value) param2 = stackElements[1].Symbol.GenericData; + else param2 = stackElements[1].Value; + genericData=GenericData.PerformConvert(param1,param2); + element.Value = genericData; + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformSubstring(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (3 != stackElements.Length) return; + StackElement result = new StackElement(); + GenericData resultData = null; + GenericData argumentData = null; + GenericData startIndexData = null; + GenericData lengthData = null; + + if (null == stackElements[0].Value) argumentData = stackElements[0].Symbol.GenericData; + else argumentData = stackElements[0].Value; + + if (null == stackElements[1].Value) startIndexData = stackElements[1].Symbol.GenericData; + else startIndexData = stackElements[1].Value; + + if (null == stackElements[2].Value) lengthData = stackElements[2].Symbol.GenericData; + else lengthData = stackElements[2].Value; + + resultData=argumentData.Substring(startIndexData,lengthData); + result.Value = resultData; + codeStack.Push(result); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformGetPrice(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (3 != stackElements.Length) return; + StackElement result = new StackElement(); + GenericData resultData = null; + GenericData symbolData = null; + GenericData dateData = null; + GenericData opData = null; + + if (null == stackElements[0].Value) symbolData = stackElements[0].Symbol.GenericData; + else symbolData = stackElements[0].Value; + + if (null == stackElements[1].Value) dateData = stackElements[1].Symbol.GenericData; + else dateData = stackElements[1].Value; + + if (null == stackElements[2].Value) opData = stackElements[2].Symbol.GenericData; + else opData = stackElements[2].Value; + + resultData=symbolData.GetPrice(dateData,opData); + result.Value = resultData; + codeStack.Push(result); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformTrim(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (1 != stackElements.Length) return; + StackElement result = new StackElement(); + GenericData resultData = null; + GenericData argumentData = null; + + if (null == stackElements[0].Value) argumentData = stackElements[0].Symbol.GenericData; + else argumentData = stackElements[0].Value; + + resultData=argumentData.Trim(); + result.Value = resultData; + codeStack.Push(result); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformUpper(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (1 != stackElements.Length) return; + StackElement result = new StackElement(); + GenericData resultData = null; + GenericData argumentData = null; + if (null == stackElements[0].Value) argumentData = stackElements[0].Symbol.GenericData; + else argumentData = stackElements[0].Value; + resultData = argumentData.Upper(); + result.Value = resultData; + codeStack.Push(result); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformLower(StackElement[] stackElements) + { + try + { + if(isInError)return; + if (1 != stackElements.Length) return; + StackElement result = new StackElement(); + GenericData resultData = null; + GenericData argumentData = null; + + if (null == stackElements[0].Value) argumentData = stackElements[0].Symbol.GenericData; + else argumentData = stackElements[0].Value; + resultData = argumentData.Lower(); + result.Value = resultData; + codeStack.Push(result); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformIn(StackElement[] stackElements) + { + try + { + if(isInError)return; + StackElement element = new StackElement(); + GenericData genericData = new GenericData(); + StackElement argument= codeStack.Pop(); + GenericData argumentData = null; + bool evaluationResult = false; + if (null != argument.Value) argumentData = argument.Value; + else argumentData = argument.Symbol.GenericData; + for (int index = 0; index < stackElements.Length; index++) + { + GenericData stackData = null; + if (null == stackElements[index].Value) stackData = stackElements[index].Symbol.GenericData; + else stackData = stackElements[index].Value; + GenericData result = stackData.EqualEqual(argumentData); + if (result.IsNull()) continue; + if(result.Get().Equals(true)) + { + evaluationResult = true; + break; + } + } + genericData.SetData(evaluationResult); + element.Value = genericData; + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformIsNull(StackElement[] stackElements) + { + try + { + if(isInError)return; + StackElement element = new StackElement(); + GenericData stackData = null; + for (int index = 0; index < stackElements.Length; index++) + { + if (null == stackElements[index].Value) stackData = stackElements[index].Symbol.GenericData; + else stackData = stackElements[index].Value; + if (!stackData.IsNull()) break; + } + element.Value = stackData; + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + public void PerformLike(StackElement[] stackElements) + { + try + { + if(isInError)return; + StackElement element = new StackElement(); + StackElement stackElement= codeStack.Pop(); + GenericData stackData = null; + GenericData genericData = null; + GenericData param1 = null; + if (1 != stackElements.Length) return; + if (null != stackElement.Value) stackData = stackElement.Value; + else stackData = stackElement.Symbol.GenericData; + if (null == stackElements[0].Value) param1 = stackElements[0].Symbol.GenericData; + else param1 = stackElements[0].Value; + if (null == stackData) { genericData = new GenericData(); genericData.SetData(false); } + else genericData=stackData.Like(param1); + element.Value = genericData; + codeStack.Push(element); + } + catch(Exception exception) + { + isInError=true; + lastMessage=exception.ToString(); + } + } + } +} diff --git a/Axiom.Core/Interpreter/AxiomException.cs b/Axiom.Core/Interpreter/AxiomException.cs new file mode 100644 index 0000000..7debdfd --- /dev/null +++ b/Axiom.Core/Interpreter/AxiomException.cs @@ -0,0 +1,21 @@ +using System; +using System.Data; + +// FileName : AxiomException.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class AxiomException : Exception + { + public AxiomResult AxiomResult{get;set;} + public AxiomException() + { + } + public AxiomException(AxiomResult axiomResult,Exception exception) + : base(exception.Message,exception) + { + this.AxiomResult=axiomResult; + } + } +} diff --git a/Axiom.Core/Interpreter/AxiomResult.cs b/Axiom.Core/Interpreter/AxiomResult.cs new file mode 100644 index 0000000..78f520d --- /dev/null +++ b/Axiom.Core/Interpreter/AxiomResult.cs @@ -0,0 +1,26 @@ +using System; +using System.Data; + +// FileName : AxiomResult.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class AxiomResult + { + public AxiomResult() + { + Success = false; + } + public AxiomResult(bool success,String lastMessage) + { + Success = success; + LastMessage = lastMessage; + } + public bool Success { get; set; } + public String LastMessage { get; set; } + public DataTable DataTable { get; set; } + public int ContextSpecificId{get;set;} + public Object ContextSpecificObj { get; set; } + } +} diff --git a/Axiom.Core/Interpreter/AxiomTrace.cs b/Axiom.Core/Interpreter/AxiomTrace.cs new file mode 100644 index 0000000..ca5b419 --- /dev/null +++ b/Axiom.Core/Interpreter/AxiomTrace.cs @@ -0,0 +1,44 @@ +using System; +using System.Configuration; +using System.Diagnostics; + +// FileName : AxiomTrace.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class AxiomTrace + { + public AxiomTrace() + { + IsTracing = false; + } + public bool IsTracing { get; set; } + public String[] Values { get; set; } + public int Column { get; set; } + + public static AxiomTrace FromConfig() + { + AxiomTrace trace = new AxiomTrace(); + try + { + String tracingEnabled = ConfigurationManager.AppSettings["AXIOM_TRACE_ENABLED"]; + if (null == tracingEnabled) return trace; + trace.IsTracing = Boolean.Parse(tracingEnabled); + trace.Column = int.Parse(ConfigurationManager.AppSettings["AXIOM_TRACE_COLUMN"]); + trace.Values = ConfigurationManager.AppSettings["AXIOM_TRACE_VALUES"].Split(','); + return trace; + } + catch (Exception /*exception*/) + { + return trace; + } + } + public bool Break() + { + if (!Debugger.IsAttached) return false; + Debugger.Break(); // if you wind up here you are in the debugger AND AXIOM_TRACE_ENABLED is set in the congifuration AND the break condition has been met. Step over this breakpoint to continue debugging OR set AXIOM_TRACE_ENABLED to false in config and restart + return true; + } + } +} diff --git a/Axiom.Core/Interpreter/CodeRunner.cs b/Axiom.Core/Interpreter/CodeRunner.cs new file mode 100644 index 0000000..00f1d05 --- /dev/null +++ b/Axiom.Core/Interpreter/CodeRunner.cs @@ -0,0 +1,422 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Data; +using log4net; +using Axiom.Utils; + +// FileName : CodeRunner.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class CodeRunner : IDisposable + { + private static ILog logger = LogManager.GetLogger(typeof(CodeRunner)); + private SymbolTable symbolTable = null; + private Dictionary precompiles = new Dictionary(); + private bool useCache=false; + private bool trace=false; + private bool parseStrict=false; + private bool scanStrict=false; + private bool disposed = false; + private int parseSymbolCount=0; + + public CodeRunner() + { + symbolTable=new SymbolTable(); + IsInError=false; + } + ~CodeRunner() + { + Dispose(false); + } + public void Dispose() + { + if (!disposed) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + protected virtual void Dispose(bool disposing) + { + if(disposing) + { + List streams=new List(precompiles.Values); + foreach(Stream stream in streams) + { + try{stream.Close();stream.Dispose();}catch(Exception){;} + } + } + 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"; + Symbol symbol = symbolTable[name]; + GenericData genericData = symbol.GenericData; + if (null == genericData || genericData.IsNull()) return "null"; + return genericData.Get(); + } + public T GetValue(String name) + { + if(!symbolTable.ContainsKey(name)) return default(T); + Symbol symbol=symbolTable[name]; + GenericData genericData=symbol.GenericData; + if(null==genericData||genericData.IsNull()) return default(T); + return genericData.Get(); + } + 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 + symbolTable.AddUserValues(dataTable.Rows[row], dataTable); + if (UseCache) + { + if (!ApplyRuleWithCache(expression)) return false; + } + else + { + if (!Execute(expression))return false; + } + return true; + } + public bool Execute(String expression) + { + BinaryReader binaryReader = null; + BinaryWriter binaryWriter = null; + BinaryReader parserReader = null; + BinaryWriter parserWriter = null; + BinaryReader assemblerReader = null; + Assembler assembler = null; + + try + { + IsInError=false; + LastMessage=""; + binaryReader = new BinaryReader(Utility.StreamFromString(expression)); + binaryWriter = new BinaryWriter(new MemoryStream()); + Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable); + scanner.Debug = Trace; + if (!scanner.Analyze()) + { + LastMessage="Failed to scan the input document, possible invalid character sequence."; + IsInError=true; + logger.ErrorFormat(LastMessage); + return false; + } + binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin); + parserReader = new BinaryReader(binaryWriter.BaseStream); + parserWriter = new BinaryWriter(new MemoryStream()); + Parser parser = new Parser(parserReader, parserWriter, symbolTable); + parser.Debug = Trace; + parser.Parse(); + parseSymbolCount=parser.ParseSymbolsCount; + if (parser.IsInError) + { + LastMessage=String.Format("Failed to parse the input, {0} at {1}", parser.LastMessage, parser.LastLineNumber); + IsInError=true; + logger.ErrorFormat(LastMessage); + return false; + } + parserWriter.BaseStream.Seek(0, SeekOrigin.Begin); + assemblerReader = new BinaryReader(parserWriter.BaseStream); + assembler = new Assembler(assemblerReader, symbolTable); + assembler.Debug = Trace; + assembler.Assemble(); + if(assembler.IsInError) + { + LastMessage=String.Format("Error: Failed to run the assembler, {0}", assembler.LastMessage); + IsInError=true; + logger.ErrorFormat(LastMessage); + return false; + } + if (Trace) DumpSymbolTable(); + assembler.Dispose(); + assembler = null; + return true; + } + catch (Exception exception) + { + LastMessage=String.Format("Exception:{0}",exception.ToString()); + IsInError=true; + logger.ErrorFormat(LastMessage); + return false; + } + finally + { + if (null != binaryReader) { binaryReader.Close();binaryReader.Dispose(); } + if (null != binaryWriter) { binaryWriter.Close();binaryWriter.Dispose(); } + if (null != parserReader) { parserReader.Close();parserReader.Dispose(); } + if (null != parserWriter) { parserWriter.Close(); parserWriter.Dispose(); } + if (null != assemblerReader) { assemblerReader.Close(); assemblerReader.Dispose(); } + if (null != assembler) { assembler.Dispose();assembler = null; } + } + } + + public List Disassemble(String expression) + { + BinaryReader binaryReader = null; + BinaryWriter binaryWriter = null; + BinaryReader parserReader = null; + BinaryWriter parserWriter = null; + BinaryReader assemblerReader = null; + Assembler assembler = null; + List disassembly=new List(); + + try + { + IsInError=false; + LastMessage=""; + binaryReader = new BinaryReader(Utility.StreamFromString(expression)); + binaryWriter = new BinaryWriter(new MemoryStream()); + Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable); + scanner.Debug = Trace; + if (!scanner.Analyze()) + { + LastMessage="Failed to scan the input document, possible invalid character sequence."; + IsInError=true; + logger.ErrorFormat(LastMessage); + return disassembly; + } + binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin); + parserReader = new BinaryReader(binaryWriter.BaseStream); + parserWriter = new BinaryWriter(new MemoryStream()); + Parser parser = new Parser(parserReader, parserWriter, symbolTable); + parser.Debug = Trace; + parser.Parse(); + parseSymbolCount=parser.ParseSymbolsCount; + if (parser.IsInError) + { + LastMessage=String.Format("Failed to parse the input, {0} at {1}", parser.LastMessage, parser.LastLineNumber); + IsInError=true; + logger.ErrorFormat(LastMessage); + return disassembly; + } + parserWriter.BaseStream.Seek(0, SeekOrigin.Begin); + assemblerReader = new BinaryReader(parserWriter.BaseStream); + assembler = new Assembler(assemblerReader, symbolTable); + assembler.Debug = Trace; + return assembler.Disassemble(); + } + catch (Exception exception) + { + LastMessage=String.Format("Exception:{0}",exception.ToString()); + IsInError=true; + logger.ErrorFormat(LastMessage); + return disassembly; + } + finally + { + if (null != binaryReader) { binaryReader.Close();binaryReader.Dispose(); } + if (null != binaryWriter) { binaryWriter.Close();binaryWriter.Dispose(); } + if (null != parserReader) { parserReader.Close();parserReader.Dispose(); } + if (null != parserWriter) { parserWriter.Close(); parserWriter.Dispose(); } + if (null != assemblerReader) { assemblerReader.Close(); assemblerReader.Dispose(); } + if (null != assembler) { assembler.Dispose();assembler = null; } + } + } + + +// The cache will not work as effectively if the expression variables are not loaded directly into the SymbolTable + public bool ApplyRuleWithCache(String expression) + { + BinaryReader assemblerReader = null; + Stream precompiledStream = null; + Assembler assembler = null; + try + { + int hashcode = expression.GetHashCode(); + if (Trace) logger.InfoFormat("Trace:{0}", expression); + if (precompiles.ContainsKey(hashcode)) + { + precompiledStream = precompiles[hashcode]; // if the precompiled cache contains the expression then fetch it + } + else + { + precompiledStream = Compile(expression,true); // otherwise compile the expression and add it to the cache. + precompiles.Add(hashcode, precompiledStream); + } + if (null == precompiledStream) return false; + precompiledStream.Seek(0, SeekOrigin.Begin); + assemblerReader = new BinaryReader(precompiledStream); + assembler = new Assembler(assemblerReader, symbolTable); + assembler.Assemble(); + if(assembler.IsInError) + { + LastMessage=String.Format("Error: Failed to run the assembler, {0}", assembler.LastMessage); + logger.ErrorFormat(LastMessage); + return false; + } + assembler.Dispose(); + assembler = null; + return true; + } + catch (Exception exception) + { + LastMessage=String.Format("Exception:{0}", exception.ToString()); + logger.ErrorFormat(LastMessage); + return false; + } + finally + { + if (null != assembler) { assembler.Dispose(); } + } + } + public AxiomResult SyntaxCheck(String expression) + { + BinaryReader binaryReader = null; + BinaryWriter binaryWriter = null; + BinaryReader parserReader = null; + BinaryWriter parserWriter = null; + AxiomResult axiomResult = new AxiomResult(); + + try + { + axiomResult.Success = true; + binaryWriter = new BinaryWriter(new MemoryStream()); + binaryReader = new BinaryReader(Utility.StreamFromString(expression)); + Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable); + if (!scanner.Analyze()) + { + axiomResult.Success = false; + axiomResult.LastMessage = "Failed to scan the input document, possible invalid character sequence."; + return axiomResult; + } + binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin); + parserReader = new BinaryReader(binaryWriter.BaseStream); + parserWriter = new BinaryWriter(new MemoryStream()); + Parser parser = new Parser(parserReader, parserWriter, symbolTable); +// parser.StrictMode=false; // we do not require all variable declarations to be present. + parser.StrictStatementMode=true; // we require at least one valid statement to be processed. + parser.Parse(); + if (parser.IsInError) + { + axiomResult.Success = false; + axiomResult.LastMessage = "Message:" + parser.LastMessage; + return axiomResult; + } + return axiomResult; + } + catch (Exception exception) + { + axiomResult.LastMessage = String.Format("Exception:{0}", exception.ToString()); + logger.Error(axiomResult.LastMessage); + return axiomResult; + } + finally + { + if (null != binaryReader) { binaryReader.Close(); binaryReader.Dispose(); } + if (null != binaryWriter) { binaryWriter.Close(); binaryWriter.Dispose(); } + if (null != parserReader) { parserReader.Close(); parserReader.Dispose(); } + if (null != parserWriter) { parserWriter.Close(); parserWriter.Dispose(); } + } + } + private Stream Compile(String expression, bool includeCodeEnd = true) + { + BinaryReader binaryReader = null; + BinaryWriter binaryWriter = null; + BinaryReader parserReader = null; + BinaryWriter parserWriter = null; + + try + { + binaryReader = new BinaryReader(Utility.StreamFromString(expression)); + binaryWriter = new BinaryWriter(new MemoryStream()); + Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable); + scanner.Debug = Trace; + if(!scanner.Analyze()) + { + LastMessage = "Failed to scan the input document, possible invalid character sequence"; + logger.Info(LastMessage); + return null; + } + binaryReader.Close(); + binaryReader.Dispose(); + binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin); + parserReader = new BinaryReader(binaryWriter.BaseStream); + parserWriter = new BinaryWriter(new MemoryStream()); + Parser parser = new Parser(parserReader, parserWriter, symbolTable); + parser.Debug = Trace; + parser.Parse(includeCodeEnd); + if (parser.IsInError) + { + LastMessage = String.Format("Error:{0} at {1}", parser.LastMessage, parser.LastLineNumber); + logger.Info(LastMessage); + return null; + } + parserReader.Close(); + parserReader.Dispose(); + parserReader = null; + binaryWriter.Close(); + binaryWriter.Dispose(); + binaryWriter = null; + parserWriter.BaseStream.Seek(0, SeekOrigin.Begin); + return parserWriter.BaseStream; + } + catch (Exception exception) + { + logger.ErrorFormat("Exception:{0}", exception.ToString()); + return null; + } + finally + { + if (null != binaryReader) { binaryReader.Close(); binaryReader.Dispose(); } + if (null != binaryWriter) { binaryWriter.Close(); binaryWriter.Dispose(); } + if (null != parserReader) { parserReader.Close();parserReader.Dispose(); } + } + } + private void DumpSymbolTable() + { + logger.Info("********************************************************* O U T P U T ************************************************"); + List list = new List(symbolTable.Values); + 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 ? "" : symbol.GenericData.ToString())); + } + } + } +} \ No newline at end of file diff --git a/Axiom.Core/Interpreter/Emitter.cs b/Axiom.Core/Interpreter/Emitter.cs new file mode 100644 index 0000000..ddb7513 --- /dev/null +++ b/Axiom.Core/Interpreter/Emitter.cs @@ -0,0 +1,204 @@ +using System; +using System.IO; +using System.Linq; +using log4net; + +// FileName : Emitter.cs +// Author : Sean Kessler + +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 bool debug = true; + + public Emitter(BinaryReader inputStream, BinaryWriter outputStream) + { + this.inputStream = inputStream; + this.outputStream = outputStream; + } + public bool Debug + { + get { return debug; } + set { debug = value; } + } + public void Emit(String literalValue) + { + if (!emitting) return; + outputStream.Write(literalValue.Length); + outputStream.Write(literalValue); + } +// ************************************************************************ + public void Emit(Scanner.ScanSymbols code) + { + if (!emitting) return; + outputStream.Write((int)code); + if(Debug)logger.Info(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()); + } + 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()); + } + 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()); + } +// ********************************************************************************************************************************************** + public long CodePointer() + { + return outputStream.BaseStream.Position; + } + public void Seek(long position) + { + outputStream.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+"]"); + + } + public void Emit(Parser.ParserSymbols code,Object value) + { + if (!emitting) return; + long positionBefore=outputStream.BaseStream.Position; + outputStream.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+"]"); + } + public void Emit(Parser.ParserSymbols code,Object value,int intValue) + { + if (!emitting) return; + long positionBefore=outputStream.BaseStream.Position; + outputStream.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+"]"); + } + 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+"]"); + } + 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+"]"); + } +// ************************************************************************ + public void Emit(int code, int op) + { + if (!emitting) return; + outputStream.Write(code); + outputStream.Write(op); + } + public void Emit(int identifier) + { + if (!emitting) return; + outputStream.Write(identifier); + } + public void Emit(byte value) + { + if (!emitting) return; + outputStream.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; + 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(); + 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; + } + } + } +} diff --git a/Axiom.Core/Interpreter/GenericData.cs b/Axiom.Core/Interpreter/GenericData.cs new file mode 100644 index 0000000..5eb916e --- /dev/null +++ b/Axiom.Core/Interpreter/GenericData.cs @@ -0,0 +1,713 @@ +using System; +using System.Text; +using log4net; +using MarketData.DataAccess; +using MarketData.MarketDataModel; +using System.Diagnostics; +using Axiom.Utils; + +// FileName : GenericData.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class GenericData + { + private static ILog logger = LogManager.GetLogger(typeof(GenericData)); + private Object objData = null; + private String objDataType = ""; + private bool isModified=false; + + public Object Data + { + set + { + objData = value; + if(null!=objData)objDataType =objData.GetType().ToString(); + } + get + { + return objData; + } + } + public bool IsNull() + { + return null == objData ? true : false; + } + public bool IsModified + { + get {return isModified;} + set {isModified=value;} + } + public static GenericData PerformConvert(GenericData data1, GenericData data2) // convert data of param1 to the type described in data2 + { + GenericData genericData = new GenericData(); + genericData.SetData(data1.GetStringRepData(),data2.Get()); + return genericData; + } + public GenericData GetPrice(GenericData dateData,GenericData opData) + { + GenericData resultData = new GenericData(); + double result=default(double); + try + { + String strSymbol=this.Get(); + DateTime date = dateData.Get(); + Price price=PricingDA.GetPrice(strSymbol,date); + if(null != price) + { + String strOperation=opData.Get().ToUpper(); + if(strOperation.Equals("OPEN"))result = price.Open; + else if(strOperation.Equals("HIGH"))result = price.High; + else if(strOperation.Equals("LOW"))result = price.Low; + else result = price.Close; + } + } + catch (Exception exception) + { + Debug.WriteLine(exception.ToString()); + } + resultData.SetData(result); + return resultData; + } + public GenericData Substring(GenericData startIndexData,GenericData lengthData) + { + GenericData resultData = new GenericData(); + String result = null; + try + { + int startIndex = startIndexData.Get(); + int length = lengthData.Get(); + String strArgument = this.Get(); + result = strArgument.Substring(startIndex - 1, length); + } + catch (Exception) + { + } + resultData.SetData(result); + return resultData; + } + public GenericData Trim() + { + GenericData resultData = new GenericData(); + String result = null; + try + { + String strArgument = this.Get(); + result = strArgument.Trim(); + } + catch (Exception) + { + } + resultData.SetData(result); + return resultData; + } + public GenericData Upper() + { + GenericData resultData = new GenericData(); + String result = null; + try + { + String strArgument = this.Get(); + result = strArgument.ToUpper(); + } + catch (Exception) + { + } + resultData.SetData(result); + return resultData; + } + public GenericData Lower() + { + GenericData resultData = new GenericData(); + String result = null; + try + { + String strArgument = this.Get(); + result = strArgument.ToLower(); + } + catch (Exception) + { + } + resultData.SetData(result); + return resultData; + } + public GenericData Like(GenericData argument) + { + GenericData genericData = new GenericData(); + String thisString = this.Get(); + String strArgument = argument.GetStringRepData(); + if (null == thisString || null == strArgument) + { + genericData.SetData(false); + return genericData; + } + strArgument = strArgument.Replace("%", null); + genericData.SetData(thisString.Contains(strArgument)); + return genericData; + } + public void SetNull() + { + objDataType="System.Nullable"; + objData=Convert.ChangeType(null,Type.GetType(objDataType)); + } + public void SetNull(String strDataType) + { + objDataType=GetTypeString(strDataType); + objData=Convert.ChangeType(null,Type.GetType(objDataType)); + } + public void SetData(double data) + { + Type targetType = data.GetType(); + objDataType = targetType.Name; + objData = data; + } + public void SetData(bool data) + { + Type targetType = data.GetType(); + objDataType = targetType.Name; + objData = data; + } + public void SetData(String data) + { + Type targetType = data.GetType(); + objDataType = targetType.Name; + objData = data; + } + public void SetData(String stringRep, String typeName) + { + Type targetType = Type.GetType(typeName); + objDataType = typeName; + objData = Convert.ChangeType(stringRep, targetType); + } + public static GenericData Clone(GenericData genericData) + { + GenericData copyGenericData = new GenericData(); + if (null == genericData) return copyGenericData; + copyGenericData.SetData(genericData.GetStringRepData(),genericData.GetStringRepType()); + return copyGenericData; + } +// ************************************************************************************************************************************************************************************* +// *********************************************************************************** L O G I C A L O P E R A T I O N S ************************************************************* +// ************************************************************************************************************************************************************************************* + public GenericData Not() + { + GenericData data = new GenericData(); + String stringRepType = GetStringRepType(); + + if (IsNull()) + { + data.SetNull(); + } + else if ("System.Boolean".Equals(stringRepType)) + { + data.Data=!(Get()); + } + else if ("System.Int32".Equals(stringRepType)) + { + data.Data = (Get() == 0); + } + else if ("System.String".Equals(stringRepType)) + { + data.Data = !(Get()); + } + else if ("System.Double".Equals(stringRepType)) + { + data.Data = (Get() == 0.00); + } + else data.SetNull(); + return data; + } + public GenericData LessEqual(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetData(false); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = Get()<=genericData.Get(); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = Get()<=genericData.Get(); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = Get().Length<=genericData.Get().Length; + } + else data.SetNull(); + return data; + } + public GenericData Or(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetData(false); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = (0.00!=Get())||(0.00!=genericData.Get()); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = (0!=Get())||(0!=genericData.Get()); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Boolean".Equals(genericData.GetStringRepType())) + { + data.Data = Get()||genericData.Get(); + } + else data.SetNull(); + return data; + } + public GenericData And(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetData(false); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = (0.00 != Get()) && (0.00 != genericData.Get()); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = (0 != Get()) && (0 != genericData.Get()); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Boolean".Equals(genericData.GetStringRepType())) + { + data.Data = Get() && genericData.Get(); + } + else data.SetNull(); + return data; + } + public GenericData Greater(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetData(false); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = Get()>genericData.Get(); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.DateTime".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = Get()>genericData.Get(); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = Get()>genericData.Get(); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = Get().Length>genericData.Get().Length; + } + else data.SetNull(); + return data; + } + public GenericData GreaterEqual(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetData(false); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = Get()>=genericData.Get(); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try + { + data.Data = Get()>=genericData.Get(); + } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = Get().Length>=genericData.Get().Length; + } + else data.SetNull(); + return data; + } + public GenericData EqualEqual(GenericData genericData) + { + GenericData data = new GenericData(); + + if (IsNull() && genericData.IsNull()) + { + data.SetData(true); + } + else if (IsNull()) + { + data.SetData(false); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try { data.Data = (0 == Get().CompareTo(genericData.Get())); } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try { data.Data = (0 == Get().CompareTo(genericData.Get())); } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = (Get().Equals(genericData.Get())); + } + else data.SetNull(); + return data; + } + public GenericData NotEqual(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull() && !genericData.IsNull()) + { + data.SetData(true); + } + else if (!IsNull() && genericData.IsNull()) + { + data.SetData(true); + } + else if (IsNull()) + { + data.SetData(false); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try { data.Data = (0 != Get().CompareTo(genericData.Get())); } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try { data.Data = (0 != Get().CompareTo(genericData.Get())); } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = !(Get().Equals(genericData.Get())); + } + else data.SetNull(); + return data; + } + public GenericData Less(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetData(false); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try { data.Data = (-1==Get().CompareTo(genericData.Get())); } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try { data.Data = (-1==Get().CompareTo(genericData.Get())); } + catch (Exception) { data.Data = 0.00; } + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = Get().Equals(genericData.Get()); + } + else data.SetNull(); + return data; + } + // ************************************************************************************************************************************************************************************** + // ********************************************************************************** M A T H E M A T I C A L O P E R A T I O N S **************************************************** + // ************************************************************************************************************************************************************************************** + public GenericData Negate() + { + GenericData data = new GenericData(); + String stringRepType = GetStringRepType(); + + if (IsNull()) + { + data.SetNull(); + } + else if ("System.Double".Equals(stringRepType)) + { + try + { + data.Data = Get() * -1.00; + } + catch (Exception) { data.Data = 0.00; } + } + else + { + try + { + data.Data = Get() * -1; + } + catch (Exception){data.SetNull();} + } + return data; + } + public GenericData Abs() + { + GenericData data = new GenericData(); + String stringRepType = GetStringRepType(); + if (IsNull()) + { + data.SetNull(); + } + if ("System.Double".Equals(stringRepType)) + { + try + { + data.Data = Math.Abs(Get()); + } + catch (Exception) { data.Data = 0.00; } + } + else + { + try + { + data.Data = Math.Abs(Get()); + } + catch (Exception) + { + data.SetNull(); + } + } + return data; + } + + public GenericData Multiply(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetNull(); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try { data.Data = Get() * genericData.Get(); } + catch (Exception) { data.Data = double.NaN; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try { data.Data = Get() * genericData.Get(); } + catch (Exception) { data.Data = Int32.MinValue; } + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + try { data.Data = Get() * genericData.Get(); } // genericData is a string but try to cast and perform the multiplication anyway + catch (Exception) { data.Data = double.NaN; } + } + else data.SetNull(); + return data; + } + public GenericData Divide(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetNull(); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + try { data.Data = Get() / genericData.Get(); } + catch (Exception) { data.Data = double.NaN; } + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + try { data.Data = Get() / genericData.Get(); } + catch (Exception) { data.Data = Int32.MinValue; } + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = double.NaN; + } + else data.SetNull(); + return data; + } + public GenericData Add(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetNull(); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + data.Data = Get()+genericData.Get(); + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + data.Data = Get()+genericData.Get(); + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = Get() + genericData.Get(); + } + else data.SetNull(); + return data; + } + public GenericData Subtract(GenericData genericData) + { + GenericData data = new GenericData(); + if (IsNull()) + { + data.SetNull(); + } + else if ("System.Double".Equals(genericData.GetStringRepType())) + { + data.Data = Get() - genericData.Get(); + } + else if ("System.Int32".Equals(genericData.GetStringRepType())) + { + data.Data = Get() - genericData.Get(); + } + else if ("System.String".Equals(genericData.GetStringRepType())) + { + data.Data = (Get()).Replace(genericData.Get(), null); + } + else data.SetNull(); + return data; + } +// ********************************************************************************************************** E N D O P E R A T I O N S ******************************************************************************************** + public String GetStringRepData() + { + if (null == objData) return null; + String stringRepType = GetStringRepType(); + return (String)Convert.ChangeType(objData, typeof(String)); + } + public String GetStringRepType() + { + if (null == objData) return "System.Nullable"; + return objData.GetType().ToString(); + } + public Type DataType + { + get + { + if (null == objData) throw new Exception("No type data for null value."); + return objData.GetType(); + } + } + public override String ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(GetStringRepType()).Append(":").Append("'").Append(GetStringRepData()).Append("'"); + return sb.ToString(); + } + public T Get() + { + T result = default(T); + try + { + result = (T)Convert.ChangeType(objData, typeof(T)); + } + catch(Exception /*exception*/) + { + result = default(T); + } + return result; + } +// ********************************************************************************************************************************************************************************** +// ************************************************************************ P U B L I C S T A T I C H E L P E R S **************************************************************** +// ********************************************************************************************************************************************************************************** + public static Object ConvertType(String destinationType,String stringRep) + { + try + { + if (destinationType.Equals("System.DBNull")) destinationType = "System.String"; + Type targetType = Type.GetType(destinationType); + String objDataType = destinationType; + Object objData = Convert.ChangeType(stringRep, targetType); + return objData; + } + catch(Exception /*exception*/) + { + return null; + } + } + public static Object ConvertType(Type targetType,String stringRep) + { + try + { + Object objData = null; + String stringRepType = targetType.ToString(); + if(targetType.Equals("System.Double")&&null==stringRep||stringRep.Equals(""))return objData; + else if (stringRepType.Equals("System.DBNull")) stringRep = "System.String"; + objData = Convert.ChangeType(stringRep, targetType); + return objData; + } + catch(Exception /*exception*/) + { + return null; + } + } + public static Type GetType(String strType) + { + strType=strType.ToUpper(); + if(strType.Equals("STRING")||strType.Equals("SYSTEM.STRING"))return Type.GetType("System.String"); + else if(strType.Equals("NUMERIC")||strType.Equals("DOUBLE")||strType.Equals("SYSTEM.DOUBLE"))return Type.GetType("System.Double"); + else if(strType.Equals("DATETIME")||strType.Equals("SYSTEM.DATETIME"))return Type.GetType("System.DateTime"); + return Type.GetType("System.String"); + } + public static String GetTypeString(String strType) + { + strType=strType.ToUpper(); + if(strType.Equals("STRING")||strType.Equals("SYSTEM.STRING"))return "System.String"; + else if(strType.Equals("NUMERIC")||strType.Equals("DOUBLE")||strType.Equals("SYSTEM.DOUBLE"))return "System.Double"; + else if(strType.Equals("DATETIME")||strType.Equals("SYSTEM.DATETIME"))return "System.DateTime"; + return "System.String"; + } + public static String ToExpressionData(System.Data.DataColumn dataColumn,String value) + { + if (dataColumn.DataType.Name.ToUpper().Equals("STRING")) return "'"+Utility.SqlString(value)+"'"; + if (dataColumn.DataType.Name.ToUpper().Equals("DATETIME")) return "'"+Utility.SqlString(value)+"'"; + return value; + } + } +} diff --git a/Axiom.Core/Interpreter/ParseSymbols.cs b/Axiom.Core/Interpreter/ParseSymbols.cs new file mode 100644 index 0000000..0050e32 --- /dev/null +++ b/Axiom.Core/Interpreter/ParseSymbols.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +// FileName : ParseSymbols.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class ParseSymbols : List + { + private Dictionary uniqueSymbols = new Dictionary(); + + public ParseSymbols() + { + } + public ParseSymbols(List symbols) + { + foreach (ParseSymbol symbol in symbols) InsertSymbols(symbol); + } + public new void Add(ParseSymbol parseSymbol) + { + InsertSymbols(parseSymbol); + } + public void InsertSymbols(ParseSymbols symbols) + { + foreach (ParseSymbol parseSymbol in symbols) + { + base.Add(parseSymbol); + if (!uniqueSymbols.ContainsKey(parseSymbol.Symbol)) uniqueSymbols.Add(parseSymbol.Symbol,parseSymbol.Symbol); + } + } + public void InsertSymbols(ParseSymbol parseSymbol) + { + base.Add(parseSymbol); + if (!uniqueSymbols.ContainsKey(parseSymbol.Symbol)) uniqueSymbols.Add(parseSymbol.Symbol,parseSymbol.Symbol); + } + public void RemoveSymbols(ParseSymbols symbols) + { + for (int index = symbols.Count - 1; index >= 0;index--) + { + ParseSymbol symbol = symbols[index]; + base.Remove(symbol); + int count = (from ParseSymbol parseSymbol in this where parseSymbol.Symbol.Equals(symbol.Symbol) select parseSymbol).Count(); + if (0 == count && uniqueSymbols.ContainsKey(symbol.Symbol)) uniqueSymbols.Remove(symbol.Symbol); + } + } + public void RemoveSymbols(ParseSymbol symbol) + { + base.Remove(symbol); + int count = (from ParseSymbol parseSymbol in this where parseSymbol.Symbol.Equals(symbol.Symbol) select parseSymbol).Count(); + if(0==count&&uniqueSymbols.ContainsKey(symbol.Symbol))uniqueSymbols.Remove(symbol.Symbol); + } + public bool SymbolIn(Scanner.ScanSymbols symbol) + { + return uniqueSymbols.ContainsKey(symbol); + } + public bool SymbolIn(ParseSymbols parseSymbols) + { + foreach (ParseSymbol symbol in parseSymbols) if (uniqueSymbols.ContainsKey(symbol.Symbol)) return true; + return false; + } + public bool SymbolIn(ParseSymbol parseSymbol) + { + return uniqueSymbols.ContainsKey(parseSymbol.Symbol); + } + } + public class ParseSymbol : IEquatable + { + private Scanner.ScanSymbols symbol; + public ParseSymbol() + { + } + public ParseSymbol(Scanner.ScanSymbols symbol) + { + this.symbol = symbol; + } + public Scanner.ScanSymbols Symbol + { + get + { + return symbol; + } + } + public bool Equals(ParseSymbol parseSymbol) + { + if (parseSymbol == null) return false; + return Symbol.Equals(parseSymbol.Symbol); + } + } +} diff --git a/Axiom.Core/Interpreter/Parser.cs b/Axiom.Core/Interpreter/Parser.cs new file mode 100644 index 0000000..e4ec75d --- /dev/null +++ b/Axiom.Core/Interpreter/Parser.cs @@ -0,0 +1,1748 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.IO; + +// FileName : Parser.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class Parser : Emitter + { + public enum ParserSymbols { undefined2, directive_clear_modified2, declare2, do2, defaddr2, goto2, add2, subtract2, multiply2, divide2, assign2, negate2, less2, lessequal2, greater2, greaterequal2, equalequal2, notequal2, variableaccess2, call2, push2, not2, codeend2, oror2, andand2, noop2 }; + public enum ErrorCodes{DivideByZero}; + private SymbolTable symbolTable; + private ParseSymbols directiveSymbols = new ParseSymbols(); + private ParseSymbols assignmentStatementSymbols = new ParseSymbols(); + private ParseSymbols statementSymbols = new ParseSymbols(); + private ParseSymbols simpleExpressionSymbols = new ParseSymbols(); + private ParseSymbols mathSymbols = new ParseSymbols(); + private ParseSymbols termSymbols = new ParseSymbols(); + private ParseSymbols factorSymbols = new ParseSymbols(); + private ParseSymbols addSymbols = new ParseSymbols(); + private ParseSymbols signSymbols = new ParseSymbols(); + private ParseSymbols expressionSymbols = new ParseSymbols(); + private ParseSymbols parseSymbols = new ParseSymbols(); + private ParseSymbols relationSymbols = new ParseSymbols(); + private ParseSymbols logicalSymbols = new ParseSymbols(); + private ParseSymbols declarationSymbols = new ParseSymbols(); + private ParseSymbols mathFunctionSymbols = new ParseSymbols(); + private ParseSymbols stringManipulationSymbols = new ParseSymbols(); + private Scanner.ScanSymbols currentSymbolType; + private double numeralValue; + 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 breakStack = new Stack(); // when we encounter a break statement we need to record the address of the code pointer + private Stack whileStack = new Stack(); // when we encounter a while 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) + { + this.symbolTable = symbolTable; + currentSymbolType = Scanner.ScanSymbols.unknown1; + CreateDeclarationSymbols(); + CreateAssignmentStatementSymbols(); + CreateStatementSymbols(); + CreateSimpleExpressionSymbols(); + CreateMathSymbols(); + CreateTermSymbols(); + CreateFactorSymbols(); + CreateAddSymbols(); + CreateSignSymbols(); + CreateExpressionSymbols(); + CreateRelationSymbols(); + CreateFunctionSymbols(); + CreateLogicalSymbols(); + CreateMathFunctionSymbols(); + CreateStringManipulationSymbols(); + IsInError = false; + LineNumber = 0; + LastLineNumber = 0; + SymbolNumber = -1; + LastSymbolNumber = -1; + StatementNumber = 0; + LastStatementNumber = 0; + LastMessage = ""; + } + public bool Parse(bool includeCodeEnd=true) + { + NextSymbol(); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.directive_clear_modified1)); + while (!(Scanner.ScanSymbols.endtext1.Equals(currentSymbolType)) && !IsInError) Statement(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.directive_clear_modified1)); + if(includeCodeEnd)Emit(Parser.ParserSymbols.codeend2); + if(StrictStatementMode && 0==StatementNumber)SyntaxError("The input document does not contain any valid statements."); + if (IsInError) return false; + if(Debug) + { + if (parseSymbols.Count != 0) Console.WriteLine("ParseSymbols is not empty."); + else Console.WriteLine("ParseSymbols, all symbols cleared from stack."); + } + return !IsInError; + } + public bool StrictStatementMode + { + get { return strictStatementMode; } + set{strictStatementMode=value;} + } + public int ParseSymbolsCount + { + get{return parseSymbols.Count;} + } + public int GetParseSymbolsCount() + { + return parseSymbols.Count; + } + public void Statement() + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.semicolon1)); + if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.directive_clear_modified1))) + { + DirectiveClearModified(); + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.declare1))) + { + DeclarationStatement(); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.label1))) + { + SyntaxError(); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1))) + { + ParseLiteral(); + } + else if (Scanner.ScanSymbols.variable1.Equals(currentSymbolType)) + { + bool assignmentStatement = PeekSymbol(new ParseSymbol(Scanner.ScanSymbols.equal1)); + VariableAccess(); + if(assignmentStatement) + { + AssignmentStatement(); + StatementNumber++; + } + } + else if (Scanner.ScanSymbols.if1.Equals(currentSymbolType)) + { + IfStatement(); + StatementNumber++; + } + else if(Scanner.ScanSymbols.break1.Equals(currentSymbolType)) + { + BreakStatement(); + StatementNumber++; + } + else if (Scanner.ScanSymbols.while1.Equals(currentSymbolType)) + { + WhileStatement(); + StatementNumber++; + } + else if (SymbolIn(termSymbols)) + { + Term(); + } + else SyntaxCheck(); + + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1)); + InsertSymbols(statementSymbols); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1))) + { + Expect(Scanner.ScanSymbols.semicolon1); + } + RemoveSymbols(statementSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.semicolon1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1)); + return; + } + public void DeclarationStatement() + { + bool moreDeclarations = true; + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.declare1); + SyntaxCheck(); + while(moreDeclarations) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + Expect(Scanner.ScanSymbols.variable1); + Emit(Parser.ParserSymbols.declare2, stringValue); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.comma1))) + { + Expect(Scanner.ScanSymbols.comma1); + SyntaxCheck(); + } + else moreDeclarations = false; + } + 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)) + { + SyntaxError("Encountered 'break' without 'while'"); + } + breakStack.Push(CodePointer()); + Expect(Scanner.ScanSymbols.break1); + } + /// + /// WhileStatement Parses WhileStatement. + ///WHILE + ///L1: B // + /// Do(L2) // Here we branch L2 when the condition is False + /// S + /// Goto(L1) // Goto L1 and re-evaluate + ///L2 + /// + public void WhileStatement() + { + long codePointerFalseInstructionAddress; + long codePointerL1; + long codePointerL2; + long codePointerTerminalAddress; + + whileStack.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;} + codePointerL1 = CodePointer(); // L1: + DoBForWhile(); // B + if(IsInError){whileStack.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;} + 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 + Seek(codePointerTerminalAddress); + } + public void HandleBreak(long codePointerL2) + { + if(0==breakStack.Count)return; + Seek(breakStack.Pop()); + Emit(Parser.ParserSymbols.goto2,codePointerL2); + + } + /// + /// B Section for While. + /// + public void DoBForWhile() + { + Stack logicalOperatorStack = new Stack(); + while (!IsInError) + { + bool inShortFunction = false; + InsertSymbols(expressionSymbols); + if (PeekSymbolIn(directiveSymbols)) inShortFunction = true; + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(logicalSymbols); + Expression(); + Relation(); + InsertSymbols(relationSymbols); + SyntaxCheck(); + if (IsInError) return; + RemoveSymbols(relationSymbols); + RemoveSymbols(logicalSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1)) + && !PeekSymbol(new ParseSymbol(Scanner.ScanSymbols.leftcurly1))) + { + RemoveSymbols(expressionSymbols); + break; + } + 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 do this 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 do this twice + RemoveSymbols(directiveSymbols); + continue; + } + } + ParseSymbol relationSymbol = new ParseSymbol(currentSymbolType); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); // going to handle while(){stmt;stmt;} and while()stmt; + InsertSymbols(logicalSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + if (!inShortFunction) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + if (SymbolIn(directiveSymbols)) + { + InsertSymbols(relationSymbols); + Directive(); + Relation(); + RemoveSymbols(relationSymbols); + } + else + { + Statement(); + } + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) Expect(Scanner.ScanSymbols.rightparen1); + 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); + } + } + if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop()); + 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; + } // while we continue to have logical expressions and we have no errors + if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop()); + } + /// + /// S Section for While. + /// + public void DoSForWhile() + { + InsertSymbols(statementSymbols); + if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) + { + Expect(Scanner.ScanSymbols.rightparen1); + Statement(); + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.leftcurly1))) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)); + Expect(Scanner.ScanSymbols.leftcurly1); + while (!IsInError) + { + Statement(); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightcurly1))) + { + Expect(Scanner.ScanSymbols.rightcurly1); + break; + } + } + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)); + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1))) + { + Expect(Scanner.ScanSymbols.semicolon1); + } + else SyntaxError(); + RemoveSymbols(statementSymbols); + } +// ************************************************************************************************************************************** + /// + /// IfStatement. + ///if B then S1 else S2 + /// + /// B + /// Do(L1) // Here we branch when the condition is False + /// S1 + /// Goto(L2) // Here we branch unconditionally + ///L1: S2 + ///L2: + /// + public void IfStatement() + { + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.if1); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + if(IsInError)return; + DoBForIf(); + if(IsInError)return; + DoSForIf(); + } + + public void DoBForIf() + { + Stack logicalOperatorStack = new Stack(); + while (!IsInError) + { + bool inShortFunction = false; + InsertSymbols(expressionSymbols); + if (PeekSymbolIn(directiveSymbols)) inShortFunction = true; + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(logicalSymbols); + Expression(); + Relation(); + InsertSymbols(relationSymbols); + SyntaxCheck(); + if (IsInError) return; + RemoveSymbols(relationSymbols); + RemoveSymbols(logicalSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + 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 do this 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 do this twice + RemoveSymbols(directiveSymbols); + continue; + } + } + ParseSymbol relationSymbol = new ParseSymbol(currentSymbolType); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.then1)); // going to handle if() then stmt; else stmt; + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); // going to handle if(){stmt;stmt;}else{stmt;stmt;} + InsertSymbols(logicalSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + if (!inShortFunction) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + if (SymbolIn(directiveSymbols)) + { + InsertSymbols(relationSymbols); + Directive(); + Relation(); + RemoveSymbols(relationSymbols); + } + else + { + Statement(); + } + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) Expect(Scanner.ScanSymbols.rightparen1); + 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); + } + } + if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop()); + 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.then1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); + RemoveSymbols(expressionSymbols); + if (!SymbolIn(expressionSymbols)&&!SymbolIn(directiveSymbols)) break; + } // while we continue to have logical expressions and we have no errors + if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop()); + } + public void DoSForIf() + { + bool containsElse=true; + long codePointerFalseInstructionAddress=0; + long codePointerFalseGotoTarget=0; + long codePointerTrueInstructionAddress=0; + long codePointerTrueGotoTarget=0; + long codePointerTerminalAddress=0; + + #region DO(L1) + codePointerFalseInstructionAddress = CodePointer(); // Do(L1) False. Get the address of where I am going to write the next instruction + Emit(Parser.ParserSymbols.defaddr2,0L); // write the next instruction with a zero. It will be filled in later with a valid address. This will be jump to condition:false + #endregion + #region S1 + InsertSymbols(statementSymbols); + if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.then1))) + { + Expect(Scanner.ScanSymbols.then1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.else1)); + Statement(); // after this statement we need to jump to the end + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.leftcurly1))) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)); + Expect(Scanner.ScanSymbols.leftcurly1); + while (!IsInError) + { + Statement(); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightcurly1))) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.else1)); + Expect(Scanner.ScanSymbols.rightcurly1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.else1)); + break; + } + } + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)); + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1))) + { + Expect(Scanner.ScanSymbols.semicolon1); + } + else SyntaxError(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.else1)); + #endregion + #region GOTO(L2) + codePointerTrueInstructionAddress = CodePointer(); + Emit(Parser.ParserSymbols.goto2,0L); + #endregion + #region L1:S2 + codePointerFalseGotoTarget = CodePointer(); // This is where instructions start for the false condition + Seek(codePointerFalseInstructionAddress); + Emit(Parser.ParserSymbols.defaddr2,codePointerFalseGotoTarget); + Seek(codePointerFalseGotoTarget); + if(!SymbolIn(new ParseSymbol(Scanner.ScanSymbols.else1)))containsElse=false; + if(containsElse) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); + Expect(Scanner.ScanSymbols.else1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.leftcurly1))) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); + InsertSymbols(statementSymbols); + Expect(Scanner.ScanSymbols.leftcurly1); + RemoveSymbols(statementSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); + while (!IsInError) + { + Statement(); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightcurly1))) + { + Expect(Scanner.ScanSymbols.rightcurly1); + break; + } + } + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)); + } + else + { + Statement(); + } + } + #endregion + #region L2 + codePointerTrueGotoTarget=CodePointer(); + Emit(Parser.ParserSymbols.noop2); + codePointerTerminalAddress = CodePointer(); + Seek(codePointerTrueInstructionAddress); + Emit(Parser.ParserSymbols.goto2,codePointerTrueGotoTarget); + Seek(codePointerTerminalAddress); + RemoveSymbols(statementSymbols); + #endregion + } +// ************************************************************************************************************** + public void Relation() + { + Stack logicalOperatorStack = new Stack(); + if (!SymbolIn(relationSymbols)) return; + while (!IsInError) + { + if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.equalequal1))) + { + logicalOperatorStack.Push(Parser.ParserSymbols.equalequal2); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + continue; + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.notequal1))) + { + logicalOperatorStack.Push(Parser.ParserSymbols.notequal2); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + continue; + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.less1))) + { + logicalOperatorStack.Push(Parser.ParserSymbols.less2); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + continue; + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.lessequal1))) + { + logicalOperatorStack.Push(Parser.ParserSymbols.lessequal2); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + continue; + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.greater1))) + { + logicalOperatorStack.Push(Parser.ParserSymbols.greater2); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + continue; + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.greaterequal1))) + { + logicalOperatorStack.Push(Parser.ParserSymbols.greaterequal2); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + continue; + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1))) + { + logicalOperatorStack.Push(Parser.ParserSymbols.oror2); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + 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(directiveSymbols); + continue; + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.less1))) + { + logicalOperatorStack.Push(Parser.ParserSymbols.less2); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + continue; + } + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Term(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + ParseSymbol relationSymbol = new ParseSymbol(currentSymbolType); + if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop()); + if (!SymbolIn(relationSymbols)&&!SymbolIn(logicalSymbols)) break; + } // while true + if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop()); + } + public void AssignmentStatement() + { + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.equal1); + if (IsInError) return; + RemoveSymbols(directiveSymbols); + RemoveSymbols(expressionSymbols); + if (SymbolIn(expressionSymbols)) + { + Expression(); + Emit(Parser.ParserSymbols.assign2); + } + else if (SymbolIn(directiveSymbols)) + { + RemoveSymbols(directiveSymbols); + RemoveSymbols(expressionSymbols); + Directive(); + if (SymbolIn(expressionSymbols)) + { + while (SymbolIn(expressionSymbols)) + { + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expression(); + RemoveSymbols(directiveSymbols); + RemoveSymbols(expressionSymbols); + } + } + else if (SymbolIn(mathSymbols)) + { + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + SimpleTerm(); + RemoveSymbols(expressionSymbols); + RemoveSymbols(directiveSymbols); + } + Emit(Parser.ParserSymbols.assign2); + } + else SyntaxError(); + } + public void VariableAccess() + { + Emit(Parser.ParserSymbols.variableaccess2,stringValue); + NextSymbol(); + } +// ******************************************************************************************************************************************************************************************************************************************************************* +// ************************************************************************************************************ B U I L T - I N F U N C T I O N S ****************************************************************************************************************** +// ******************************************************************************************************************************************************************************************************************************************************************* + public void Directive() + { + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.abs1))) ParseABS(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.pow1))) ParsePOW(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.sqrt1))) ParseSQRT(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.convert1))) ParseConvert(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.substring1))) ParseSubstring(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.getprice1))) ParseGetPrice(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.in1))) ParseIn(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.like1))) ParseLike(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.isnull1))) ParseIsNull(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.trim1))) ParseTrim(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.upper1))) ParseUpper(); + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.lower1))) ParseLower(); + } + public void ParseLike() + { + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.like1); + Expect(Scanner.ScanSymbols.like1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1))) + { + Emit(Parser.ParserSymbols.push2, stringValue); + Expect(Scanner.ScanSymbols.literal1); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + VariableAccess(); + } + else SyntaxCheck(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1); + } + public void ParseTrim() + { + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.trim1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.trim1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(directiveSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expression(); + InsertSymbols(addSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1); + } + public void ParseUpper() + { + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.upper1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.upper1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(directiveSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expression(); + InsertSymbols(addSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1); + } + public void ParseLower() + { + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.lower1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.lower1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(directiveSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expression(); + InsertSymbols(addSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1); + } +// SUBSTRING("",START_INDEX,LENGTH) + public void ParseSubstring() + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.substring1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(directiveSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + Expression(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.comma1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + Expression(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.comma1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expression(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(addSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.substring1); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,3); + } +// GETPRICE("MIDD",'07-13-2021','OPEN') 'OPEN'|'HIGH'|'LOW'|'CLOSE' + public void ParseGetPrice() + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.getprice1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(directiveSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + Expression(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.comma1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + Expression(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.comma1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expression(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(addSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.getprice1); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,3); + } + public void ParseConvert() + { + InsertSymbols(addSymbols); + InsertSymbols(mathSymbols); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.convert1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1))) + { + Emit(Parser.ParserSymbols.push2,stringValue); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + Expect(Scanner.ScanSymbols.literal1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + VariableAccess(); + } + else SyntaxError(); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.comma1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1))) + { + Emit(Parser.ParserSymbols.push2,stringValue); + Expect(Scanner.ScanSymbols.literal1); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + VariableAccess(); + } + else SyntaxError(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(addSymbols); + InsertSymbols(mathSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + RemoveSymbols(mathSymbols); + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.convert1); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,2); + RemoveSymbols(addSymbols); + RemoveSymbols(mathSymbols); + } + public void ParseABS() + { + InsertSymbols(addSymbols); + InsertSymbols(mathSymbols); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.abs1); + InsertSymbols(expressionSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.leftparen1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expression(); + RemoveSymbols(expressionSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(addSymbols); + InsertSymbols(mathSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + RemoveSymbols(mathSymbols); + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.abs1); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1); + RemoveSymbols(addSymbols); + RemoveSymbols(mathSymbols); + } + public void ParseSQRT() + { + InsertSymbols(addSymbols); + InsertSymbols(mathSymbols); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.sqrt1); + InsertSymbols(expressionSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.leftparen1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expression(); + RemoveSymbols(expressionSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(addSymbols); + InsertSymbols(mathSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + RemoveSymbols(mathSymbols); + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.sqrt1); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1); + RemoveSymbols(addSymbols); + RemoveSymbols(mathSymbols); + } + public void ParsePOW() + { + InsertSymbols(addSymbols); + InsertSymbols(mathSymbols); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.pow1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(directiveSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + Expression(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(directiveSymbols); + Expect(Scanner.ScanSymbols.comma1); + RemoveSymbols(directiveSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expression(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(addSymbols); + InsertSymbols(mathSymbols); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(addSymbols); + RemoveSymbols(mathSymbols); + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.pow1); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,2); + RemoveSymbols(addSymbols); + RemoveSymbols(mathSymbols); + } +// ****************************************************************************************************************************************************************************************************************** +// ***************************************************************************************************** B U I L T - I N B O O L E A N ********************************************************************************************** +// ****************************************************************************************************************************************************************************************************************** + public void ParseIn() + { + int arguments = 0; + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.in1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.in1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + while (!IsInError) + { + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) break; + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1))) + { + Emit(Parser.ParserSymbols.push2,stringValue); + arguments++; + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expect(Scanner.ScanSymbols.literal1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + VariableAccess(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + arguments++; + } + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.comma1))) + { + Expect(Scanner.ScanSymbols.comma1); + } + } + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,arguments); + } + public void ParseIsNull() + { + int arguments = 0; + Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.isnull1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + Expect(Scanner.ScanSymbols.isnull1); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Expect(Scanner.ScanSymbols.leftparen1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + while (!IsInError) + { + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) break; + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1))) + { + Emit(Parser.ParserSymbols.push2, stringValue); + arguments++; + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expect(Scanner.ScanSymbols.literal1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + VariableAccess(); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + arguments++; + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1))) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + Emit(Parser.ParserSymbols.push2, numeralValue); + Expect(Scanner.ScanSymbols.numeral1); + arguments++; + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1)); + } + else SyntaxError(); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.comma1))) + { + Expect(Scanner.ScanSymbols.comma1); + } + } + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,arguments); + } +// ******************************************************************************************************************************************************************************************************************************************************************* +// ************************************************************************************************************ E N D B U I L T - I N F U N C T I O N S ****************************************************************************************************************** +// ******************************************************************************************************************************************************************************************************************************************************************* + public void Term() + { + InsertSymbols(mathSymbols); + InsertSymbols(relationSymbols); + Factor(); + RemoveSymbols(relationSymbols); + SimpleTerm(); + RemoveSymbols(mathSymbols); + return; + } + public void SimpleTerm() + { + while (SymbolIn(mathSymbols)) + { + Scanner.ScanSymbols currSymbol = currentSymbolType; + InsertSymbols(factorSymbols); + InsertSymbols(mathFunctionSymbols); + Expect(currentSymbolType); + RemoveSymbols(factorSymbols); + RemoveSymbols(mathFunctionSymbols); + Factor(); + if (Scanner.ScanSymbols.asterisk1.Equals(currSymbol)) + { + Emit(Parser.ParserSymbols.multiply2); + } + else if (Scanner.ScanSymbols.divide1.Equals(currSymbol)) + { + Emit(Parser.ParserSymbols.divide2); + } + } + } + public void Factor() + { + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1))) + { + Emit(Parser.ParserSymbols.push2, numeralValue); + Expect(currentSymbolType); + if (SymbolIn(relationSymbols)) Relation(); + SyntaxCheck(); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + VariableAccess(); + if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.in1))) ParseIn(); + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.like1)))ParseLike(); + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.like1)))ParseTrim(); + else if (SymbolIn(relationSymbols)) Relation(); + SyntaxCheck(); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1))) + { + Emit(Parser.ParserSymbols.push2,stringValue); + Expect(currentSymbolType); + SyntaxCheck(); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.null1))) + { + EmitAsNull(Parser.ParserSymbols.push2); + Expect(currentSymbolType); + SyntaxCheck(); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.leftparen1))) + { + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + InsertSymbols(expressionSymbols); + InsertSymbols(directiveSymbols); + Expect(currentSymbolType); + RemoveSymbols(directiveSymbols); + RemoveSymbols(expressionSymbols); + if (SymbolIn(directiveSymbols)) Directive(); + Expression(); + Relation(); + Expect(Scanner.ScanSymbols.rightparen1); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1)); + SyntaxCheck(); + } + else if (SymbolIn(directiveSymbols)) + { + Directive(); + } + else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.minus1))) + { + SimpleExpression(); + } + else + { + SyntaxError(); + } + } + public void Expression() + { + while (SymbolIn(expressionSymbols)||SymbolIn(directiveSymbols)) + { + SimpleExpression(); + } + } + public void SimpleExpression() + { + InsertSymbols(addSymbols); + InsertSymbols(termSymbols); + InsertSymbols(signSymbols); + InsertSymbols(directiveSymbols); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.null1)); + SyntaxCheck(); + RemoveSymbols(signSymbols); + RemoveSymbols(directiveSymbols); + if (SymbolIn(signSymbols)) + { + Scanner.ScanSymbols currSymbol = currentSymbolType; + Expect(currentSymbolType); + if (Scanner.ScanSymbols.minus1.Equals(currSymbol)) + { + if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1))) + { + Emit(Parser.ParserSymbols.push2, numeralValue); + Expect(Scanner.ScanSymbols.numeral1); + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + VariableAccess(); + } + else SyntaxError(); + Emit(Parser.ParserSymbols.negate2); + } + else if (Scanner.ScanSymbols.plus1.Equals(currSymbol)) + { + if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1))) + { + Emit(Parser.ParserSymbols.push2, numeralValue); + Expect(Scanner.ScanSymbols.numeral1); + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + VariableAccess(); + } + //else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.convert1))) // sean 09/06 I think this needs to be al of the directive symbols + //{ + // ParseConvert(); + //} + else if(SymbolIn(directiveSymbols)) // sean 09/06 I think this needs to be al of the directive symbols + { + Directive(); + } + else SyntaxError(); + Emit(Parser.ParserSymbols.add2); + } + else if (Scanner.ScanSymbols.not1.Equals(currSymbol)) + { + if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1))) + { + Emit(Parser.ParserSymbols.push2, numeralValue); + Expect(Scanner.ScanSymbols.numeral1); + } + else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1))) + { + VariableAccess(); + } + else SyntaxError(); + Emit(Parser.ParserSymbols.not2); + } + RemoveSymbols(termSymbols); + } + else + { + RemoveSymbols(termSymbols); + Term(); + } + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.null1)); + while (SymbolIn(addSymbols)) + { + Scanner.ScanSymbols currSymbol = currentSymbolType; + InsertSymbols(termSymbols); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.null1)); + InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.isnull1)); + InsertSymbols(stringManipulationSymbols); + Expect(currentSymbolType); + RemoveSymbols(stringManipulationSymbols); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.null1)); + RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.isnull1)); + RemoveSymbols(termSymbols); + Term(); + if (Scanner.ScanSymbols.plus1.Equals(currSymbol)) + { + Emit(ParserSymbols.add2); + } + else if (Scanner.ScanSymbols.minus1.Equals(currSymbol)) + { + Emit(ParserSymbols.subtract2); + } + else SyntaxError(); + } + RemoveSymbols(addSymbols); + } +// ********************************************************************************************************************************************************************************************************************* +// ******************************************************************************************************* S Y M B O L M A N A G E M E N T ************************************************************************** +// ********************************************************************************************************************************************************************************************************************* + public bool NextSymbol() + { + numeralValue = 0.00; + int code = 0; + int result = Read(ref code); + if (result == 0xFFFF) return false; + currentSymbolType = (Scanner.ScanSymbols)code; + while (Scanner.ScanSymbols.newline1.Equals(currentSymbolType)) + { + if (0xFFFF == Read(ref code)) return false; + currentSymbolType=(Scanner.ScanSymbols)code; + LineNumber++; + SymbolNumber=-1; // make sure the symbol number is relative zero so it conforms to the rest of the line numbers (which are relative zero) + } + if (Scanner.ScanSymbols.numeral1.Equals(currentSymbolType)) + { + SymbolNumber++; + Read(ref numeralValue); + } + else if (Scanner.ScanSymbols.label1.Equals(currentSymbolType)) + { + SymbolNumber++; + Read(ref stringValue); + } + else if (Scanner.ScanSymbols.literal1.Equals(currentSymbolType)) + { + SymbolNumber++; + Read(ref stringValue); + } + else if (Scanner.ScanSymbols.variable1.Equals(currentSymbolType)) + { + SymbolNumber++; + Read(ref stringValue); + } + else if(Scanner.ScanSymbols.unknown1.Equals(currentSymbolType)) + { + SymbolNumber++; + Read(ref stringValue); + SyntaxError(); + } + return true; + } + public bool SymbolIn(ParseSymbols parseSymbols) + { + return parseSymbols.SymbolIn(new ParseSymbol(currentSymbolType)); + } + public bool SymbolIn(ParseSymbol parseSymbol) + { + return new ParseSymbol(currentSymbolType).Equals(parseSymbol); + } + public bool PeekSymbol(ParseSymbol parseSymbol) + { + Scanner.ScanSymbols peekSymbol; + int intPeek = 0; +// PeekIgnore(ref intPeek,(int)Scanner.ScanSymbols.newline1); + PeekIgnore(ref intPeek,new int[]{(int)Scanner.ScanSymbols.newline1,(int)Scanner.ScanSymbols.unknown1}); + peekSymbol = (Scanner.ScanSymbols)intPeek; + if (new ParseSymbol(peekSymbol).Equals(parseSymbol)) return true; + return false; + } + public bool PeekSymbolIn(ParseSymbols parseSymbols) + { + Scanner.ScanSymbols peekSymbol; + int intPeek = 0; + PeekIgnore(ref intPeek,new int[]{(int)Scanner.ScanSymbols.newline1,(int)Scanner.ScanSymbols.unknown1}); + peekSymbol = (Scanner.ScanSymbols)intPeek; + return parseSymbols.SymbolIn(peekSymbol); + } + public void Expect(Scanner.ScanSymbols symbol) + { + if (symbol.Equals(currentSymbolType)) NextSymbol(); + else SyntaxError(symbol); + SyntaxCheck(); + } + public void InsertSymbols(ParseSymbols groupSymbols) + { + parseSymbols.InsertSymbols(groupSymbols); + } + public void RemoveSymbols(ParseSymbols removeSymbols) + { + parseSymbols.RemoveSymbols(removeSymbols); + } + public void InsertSymbols(ParseSymbol parseSymbol) + { + parseSymbols.InsertSymbols(parseSymbol); + } + public void RemoveSymbols(ParseSymbol parseSymbol) + { + parseSymbols.RemoveSymbols(parseSymbol); + } + public bool IsInError { get; set; } + public int LineNumber { get; set; } + public int LastLineNumber { get; set; } + public int SymbolNumber { get; set; } + public int LastSymbolNumber { get; set; } + public int StatementNumber { get; set; } + public int LastStatementNumber { get; set; } + public String LastMessage { get; set; } +// ************************************************************************************************************************************************************************************************************** +// ******************************************************************************************************* E R R O R H A N D L I N G ************************************************************************** +// ************************************************************************************************************************************************************************************************************** + public void SyntaxCheck() + { + if (!parseSymbols.SymbolIn(currentSymbolType)) SyntaxError(); + } + public void SyntaxError(Scanner.ScanSymbols symbol) + { + ErrorExpect(symbol); + while (!parseSymbols.SymbolIn(currentSymbolType) && NextSymbol()) ; + } + public void SyntaxError(String specificError) + { + if (!IsInError) + { + LastMessage=String.Format(" {0} at line: {1} statement: {2} symbol: {3}",specificError,LineNumber,StatementNumber,SymbolNumber); + LastLineNumber = LineNumber; + LastSymbolNumber = SymbolNumber; + LastStatementNumber = StatementNumber; + IsInError = true; + } + } + public void SyntaxError() + { + if (!IsInError) + { + if(Scanner.ScanSymbols.unknown1.Equals(currentSymbolType))LastMessage = String.Format(" Unexpected Symbol '{0}' at line: {1} statement: {2} symbol: {3}",stringValue,LineNumber,StatementNumber,SymbolNumber); + else LastMessage = String.Format(" Unexpected Symbol '{0}' at line: {1} statement: {2} symbol: {3}",Scanner.SymbolToLiteralString(currentSymbolType),LineNumber,StatementNumber,SymbolNumber); + LastLineNumber = LineNumber; + LastSymbolNumber = SymbolNumber; + LastStatementNumber = StatementNumber; + IsInError = true; + } + while (!parseSymbols.SymbolIn(currentSymbolType) && NextSymbol()) ; + } + void ErrorExpect(Scanner.ScanSymbols symbolType) + { + if (IsInError) return; + LastMessage=String.Format(" Expected Symbol {0} at line: {1} statement: {2} symbol: {3}",Scanner.SymbolToLiteralString(symbolType),LineNumber,StatementNumber,SymbolNumber); + LastLineNumber = LineNumber; + LastSymbolNumber = SymbolNumber; + LastStatementNumber = StatementNumber; + IsInError = true; + } + public void Error(Parser.ErrorCodes errorCode, String message = null) + { + if (IsInError) return; + switch (errorCode) + { + case Parser.ErrorCodes.DivideByZero : + LastMessage = ""; + LastLineNumber = LineNumber; + break; + } + } +// *********************************************************************************************************************************************************************************************************************************************** +// ***************************************************************************************************** C R E A T E S Y M B O L S ************************************************************************************************************ +// *********************************************************************************************************************************************************************************************************************************************** + private void CreateDeclarationSymbols() + { + declarationSymbols.Clear(); + declarationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.declare1)); + } + private void CreateAssignmentStatementSymbols() + { + assignmentStatementSymbols.Clear(); + assignmentStatementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.equal1)); + } + private void CreateStatementSymbols() + { + statementSymbols.Clear(); + statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.variable1)); + statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.label1)); + 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.declare1)); + statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.break1)); + } + private void CreateSimpleExpressionSymbols() + { + simpleExpressionSymbols.Clear(); + simpleExpressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.plus1)); + simpleExpressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.minus1)); + simpleExpressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + simpleExpressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + } + private void CreateMathSymbols() + { + mathSymbols.Clear(); + mathSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.asterisk1)); + mathSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.divide1)); + } + private void CreateTermSymbols() + { + termSymbols.Clear(); + termSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + termSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + } + private void CreateFactorSymbols() + { + factorSymbols.Clear(); + factorSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + factorSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + factorSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.variable1)); + } + private void CreateAddSymbols() + { + addSymbols.Clear(); + addSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.minus1)); + addSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.plus1)); + } + private void CreateSignSymbols() + { + signSymbols.Clear(); + signSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.minus1)); + signSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.plus1)); + signSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.not1)); + } + private void CreateExpressionSymbols() + { + expressionSymbols.Clear(); + expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.leftparen1)); + expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.minus1)); + expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.plus1)); + expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.numeral1)); + expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.variable1)); + expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.literal1)); + expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.not1)); + expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.null1)); + } + private void CreateFunctionSymbols() + { + List symbols = new List(symbolTable.Values); + List directiveSymbolsList = (from Symbol symbol in symbols where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.FunctionSymbol) select symbol).ToList(); + foreach (Symbol symbol in directiveSymbolsList) directiveSymbols.Add(new ParseSymbol(symbol.Identifier)); + } + private void CreateRelationSymbols() + { + relationSymbols.Clear(); + relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.less1)); + relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.lessequal1)); + relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.greater1)); + relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.greaterequal1)); + relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.notequal1)); + relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.equalequal1)); + } + private void CreateLogicalSymbols() + { + logicalSymbols.Clear(); + logicalSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.andand1)); + logicalSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.oror1)); + } + private void CreateMathFunctionSymbols() + { + mathFunctionSymbols.Clear(); + mathFunctionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.abs1)); + mathFunctionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.sqrt1)); + mathFunctionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.pow1)); + mathFunctionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.convert1)); + } + private void CreateStringManipulationSymbols() + { + stringManipulationSymbols.Clear(); + stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.substring1)); + stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.trim1)); + stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.upper1)); + stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.lower1)); + stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.convert1)); + } + public static String SymbolToString(Parser.ParserSymbols code) + { + switch (code) + { + case Parser.ParserSymbols.directive_clear_modified2 : + return "directive_clear_modified2"; + case Parser.ParserSymbols.declare2 : + return "declare2"; + case Parser.ParserSymbols.undefined2 : + return "undefined2"; + case Parser.ParserSymbols.add2 : + return "add2"; + case Parser.ParserSymbols.subtract2 : + return "subtract2" ; + case Parser.ParserSymbols.multiply2 : + return "multiply2"; + case Parser.ParserSymbols.divide2 : + return "divide2"; + case Parser.ParserSymbols.assign2 : + return "assign2"; + case Parser.ParserSymbols.negate2 : + return "negate2"; + case Parser.ParserSymbols.variableaccess2 : + return "variableaccess2"; + case Parser.ParserSymbols.call2 : + return "call2"; + case Parser.ParserSymbols.push2 : + return "push2"; + case Parser.ParserSymbols.codeend2 : + return "codeend2"; + case Parser.ParserSymbols.do2 : + return "do2"; + case Parser.ParserSymbols.defaddr2 : + return "defaddr2"; + case Parser.ParserSymbols.goto2 : + return "goto2"; + case Parser.ParserSymbols.less2 : + return "less2"; + case Parser.ParserSymbols.lessequal2 : + return "lessequal2"; + case Parser.ParserSymbols.greater2 : + return "greater2"; + case Parser.ParserSymbols.greaterequal2 : + return "greaterequal2"; + case Parser.ParserSymbols.equalequal2 : + return "equalequal2" ; + case Parser.ParserSymbols.noop2 : + return "noop2" ; + case Parser.ParserSymbols.not2 : + return "not2" ; + case Parser.ParserSymbols.oror2 : + return "oror2" ; + case Parser.ParserSymbols.andand2 : + return "andand2" ; + default : + return "undefined code "+(int)code; + } + } + } +} \ No newline at end of file diff --git a/Axiom.Core/Interpreter/Scanner.cs b/Axiom.Core/Interpreter/Scanner.cs new file mode 100644 index 0000000..d3bc546 --- /dev/null +++ b/Axiom.Core/Interpreter/Scanner.cs @@ -0,0 +1,625 @@ +using System; +using System.Text; +using System.IO; + +// FileName : ParseSymbols.cs +// Author : Sean Kessler + +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 }; + private enum WhiteSpace{spacechar=32,tabchar=9}; + private int character; + private StringBuilder word; + private SymbolTable symbolTable; + + public Scanner(BinaryReader binaryReader, BinaryWriter binaryWriter,SymbolTable symbolTable) + : base(binaryReader, binaryWriter) + { + this.symbolTable = symbolTable; + } + public bool Analyze() + { + if(!ReadCh())return false; + while ((int)character != -1 && character != 0x001A) + { + SkipSeparators(); + if(-1==(int)character)break; + if (0xFFFF == character || 0x001A == character) break; + if (IsDigit(character) || '.'.Equals((char)character)) ScanNumeral(); + else if ('\r' == character) ScanNewLine(); + else if (';' == character) { Emit(ScanSymbols.semicolon1); ReadCh(); } + else if (',' == character) { Emit(ScanSymbols.comma1); ReadCh(); } + else if ('[' == character) { Emit(ScanSymbols.leftbracket1); ReadCh(); } + else if (']' == character) { Emit(ScanSymbols.rightbracket1); ReadCh(); } + else if ('*' == character) { Emit(ScanSymbols.asterisk1); ReadCh(); } + else if ('/' == character) { ScanDivide(); } + else if ('+' == character) { Emit(ScanSymbols.plus1); ReadCh(); } + else if ('-' == character) { Emit(ScanSymbols.minus1); ReadCh(); } + else if ('(' == character) { Emit(ScanSymbols.leftparen1); ReadCh(); } + else if (')' == character) { Emit(ScanSymbols.rightparen1); ReadCh(); } + else if ('!' == character) { Emit(ScanSymbols.not1); ReadCh(); } + else if ('{' == character) { Emit(ScanSymbols.leftcurly1); ReadCh(); } + else if ('}' == character) { Emit(ScanSymbols.rightcurly1); ReadCh(); } + else if ('\'' == character) ScanLiteral(); + else if (';' == character) ScanComment(); + else if ('=' == character) ScanEqual(); + else if ('<' == character) ScanLess(); + else if ('>' == character) ScanGreater(); + else if ('&' == character) ScanAnd(); + else if ('|' == character) ScanOr(); + else if (IsAlpha(character)) + { + if (!ScanWord()) return false; + } + else if ('#' == character) + { + if (!ScanDirective()) return false; + } + else + { + ScanUnknown(); + return false; + } + } + Emit(Scanner.ScanSymbols.endtext1); + return true; + } + public bool ReadCh() + { + try + { + character = Read(); + if (-1 == character) return false; + return true; + } + catch(Exception) + { + character = -1; + return false; + } + } + public void ScanDivide() + { + Emit(ScanSymbols.divide1); + ReadCh(); + } + public bool PeekCh(ref char ch) + { + try + { + int character=Peek(); + if(-1==character)return false; + ch=(Char)character; + return true; + } + catch(Exception) + { + return false; + } + } + public bool ScanDirective() + { + char nextChar='\0'; + if(!PeekCh(ref nextChar))return false; + if(!nextChar.Equals('#'))return ScanWord(); + while (-1!=character && 0x0D != character && 0xFFFF != character)ReadCh(); // if we have ## then take the line as a comment + return true; + } + public bool ScanWord() + { + StringBuilder sb = new StringBuilder(); + while (-1!=character && 0x0D != character && !IsKeySymbol() && 0xFFFF != character && (int)WhiteSpace.spacechar!=character && (int)WhiteSpace.tabchar != character) + { + sb.Append((char)character); + ReadCh(); + } + if (0 == sb.Length) return true; + String symbolName = sb.ToString(); + if (':'.Equals((char)character)) + { + Emit(ScanSymbols.label1); + Emit(symbolName); + ReadCh(); + } + else if(symbolTable.ContainsKey(symbolName)) + { + Symbol symbol = symbolTable[symbolName]; + if (Symbol.SymbolType.FunctionSymbol.Equals(symbol.TypeOfSymbol)) Emit(symbol.Identifier); + else if(Symbol.SymbolType.KeywordSymbol.Equals(symbol.TypeOfSymbol)) Emit(symbol.Identifier); + else if(Symbol.SymbolType.DirectiveSymbol.Equals(symbol.TypeOfSymbol)) Emit(symbol.Identifier); + else Emit(ScanSymbols.variable1, symbol.SymbolName); + } + else if(symbolTable.ContainsKey(symbolName.ToLower())) + { + symbolName = symbolName.ToLower(); + Symbol symbol = symbolTable[symbolName]; + if (Symbol.SymbolType.FunctionSymbol.Equals(symbol.TypeOfSymbol)) Emit(symbol.Identifier); + else if(Symbol.SymbolType.KeywordSymbol.Equals(symbol.TypeOfSymbol)) Emit(symbol.Identifier); + else Emit(ScanSymbols.variable1, symbol.SymbolName); + } + else + { + Emit(ScanSymbols.variable1, symbolName); + } + return true; + } + public bool ScanNumeral() + { + int[] chBuffer = new int[128]; + int chIndex = 0; + while (0xFFFF != character && (IsDigit(character) || IsInHex(character) || '.'.Equals((char)character))) + { + if (chIndex >= chBuffer.Length) return false; + chBuffer[chIndex++] = character; + ReadCh(); + } + if (character == 69) Exponent(chBuffer, chIndex); + else if ('h' == character || 'H' == character) { Hex(chBuffer, chIndex); ReadCh(); } + else if ('b' == character || 'B' == character) { Binary(chBuffer, chIndex); ReadCh(); } + else if (chIndex > 0 && ('b' == chBuffer[chIndex - 1] || 'B' == chBuffer[chIndex - 1])) Binary(chBuffer, chIndex - 1); + else Decimal(chBuffer, chIndex); + return true; + } + public void Exponent(int[] chBuffer, int chIndex) + { + chBuffer[chIndex++] = character; + ReadCh(); + while (0xFFFF != character && (character == 43 || character == 45 || IsDigit(character))) + { + if (chIndex >= chBuffer.Length) return; + chBuffer[chIndex++] = character; + ReadCh(); + } + Decimal(chBuffer, chIndex); + } + public void Binary(int[] chBuffer,int chIndex) + { + int value=0; + int multiplier=1; + + for(--chIndex;chIndex>=0;chIndex--) + { + switch(chBuffer[chIndex]) + { + case '0' : break; + case '1' : {value+=multiplier;break;} + default : {Emit(ScanSymbols.unknown1);return;} + } + multiplier*=2; + } + Emit(ScanSymbols.numeral1,value); + } + public void Decimal(int[] chBuffer,int chIndex) + { + StringBuilder sb = new StringBuilder(); + for (int index = 0; index < chBuffer.Length; index++) sb.Append((char)chBuffer[index]); + double value = double.Parse(sb.ToString()); + Emit(ScanSymbols.numeral1,value); + } + public bool IsInHex(int character) + { + if ('A'.Equals(character) || 'B'.Equals(character) || 'C'.Equals(character) || 'D'.Equals(character) || 'E'.Equals(character) || 'F'.Equals(character) || + 'a'.Equals(character) || 'b'.Equals(character) || 'c'.Equals(character) || 'd'.Equals(character) || 'e'.Equals(character) || 'f'.Equals(character)) return true; + return false; + } + void Hex(int[] chBuffer, int chIndex) + { + int value=0; + int multiplier=1; + + for(--chIndex;chIndex>=0;chIndex--) + { + switch(chBuffer[chIndex]) + { + case '0' : break; + case '1' : {value+=multiplier;break;} + case '2' : {value+=multiplier*2;break;} + case '3' : {value+=multiplier*3;break;} + case '4' : {value+=multiplier*4;break;} + case '5' : {value+=multiplier*5;break;} + case '6' : {value+=multiplier*6;break;} + case '7' : {value+=multiplier*7;break;} + case '8' : {value+=multiplier*8;break;} + case '9' : {value+=multiplier*9;break;} + case 'a' : + case 'A' : {value+=multiplier*10;break;} + case 'b' : + case 'B' : {value+=multiplier*11;break;} + case 'c' : + case 'C' : {value+=multiplier*12;break;} + case 'd' : + case 'D' : {value+=multiplier*13;break;} + case 'e' : + case 'E' : {value+=multiplier*14;break;} + case 'f' : + case 'F' : {value+=multiplier*15;break;} + default : {Emit(ScanSymbols.unknown1);return;} + } + multiplier*=16; + } + Emit(ScanSymbols.numeral1,value); + } + + public void SkipSeparators() + { + while (character.Equals((int)WhiteSpace.spacechar) || character.Equals((int)WhiteSpace.tabchar)) ReadCh(); + } + public void ScanNewLine() + { + Emit(ScanSymbols.newline1); + ReadCh(); + while (character.Equals('\n') || character.Equals('\n')) ReadCh(); + } + public void ScanAnd() + { + int character=0; + + Peek(ref character); + if ('&'.Equals((char)character)) + { + Emit(ScanSymbols.andand1); + ReadCh(); + ReadCh(); + } + else + { + Emit(ScanSymbols.unknown1); + ReadCh(); + } + } + public void ScanOr() + { + int character=0; + + Peek(ref character); + if ('|'.Equals((char)character)) + { + Emit(ScanSymbols.oror1); + ReadCh(); + ReadCh(); + } + else + { + Emit(ScanSymbols.unknown1); + ReadCh(); + } + } + public void ScanEqual() + { + int character=0; + + Peek(ref character); + if ('='.Equals((char)character)) + { + Emit(ScanSymbols.equalequal1); + ReadCh(); + ReadCh(); + } + else + { + Emit(ScanSymbols.equal1); + ReadCh(); + } + } + public void ScanLess() + { + int character=0; + + Peek(ref character); + if ('='.Equals((char)character)) + { + Emit(ScanSymbols.lessequal1); + ReadCh(); + ReadCh(); + } + else if ('>'.Equals((char)character)) + { + Emit(ScanSymbols.notequal1); + ReadCh(); + ReadCh(); + } + else + { + Emit(ScanSymbols.less1); + ReadCh(); + } + } + public void ScanGreater() + { + int character=0; + + Peek(ref character); + if ('='.Equals((char)character)) + { + Emit(ScanSymbols.greaterequal1); + ReadCh(); + ReadCh(); + } + else + { + Emit(ScanSymbols.greater1); + ReadCh(); + } + } + public void ScanComment() + { + ReadCh(); + while(!character.Equals('\r')&&!character.Equals(0xFFFF))ReadCh(); + } + public bool IsAlpha(int character) + { + return Char.IsLetter((char)character); + } + public bool IsDigit(int character) + { + return Char.IsDigit((char)character); + } + public bool IsKeySymbol() + { + return ('}'==character||'{'==character||'<'==character||'>'==character||';'==character || ' ' == character || ',' == character || '[' == character || ']' == character || ':' == character || '*' == character || '/' == character || '+' == character || '-' == character || '(' == character || ')' == character ||'='==character); + } + public void ScanLiteral() + { + int character; + word = new StringBuilder(); + ReadCh(); + character = this.character; + if (character == '\'') + { + Emit(ScanSymbols.literal1,word.ToString()); + ReadCh(); + return; + } + while (-1!=character && 0xFFFF != this.character && 0x0D != this.character) + { + if ('\'' == this.character) + { + char peekChar=(char)0; + PeekCh(ref peekChar); + if ('\'' != peekChar) break; + ReadCh(); + } + word.Append((char)this.character); + if (!ReadCh()) break; + } + ReadCh(); + Emit(ScanSymbols.literal1,word.ToString()); + } + public void ScanUnknown() + { + ReadCh(); + Emit(ScanSymbols.unknown1); + } + public static String SymbolToLiteralString(Scanner.ScanSymbols code) + { + switch(code) + { + case Scanner.ScanSymbols.directive_clear_modified1 : + return "directive_clear_modified1"; + case Scanner.ScanSymbols.declare1 : + return "declare"; + case Scanner.ScanSymbols.unknown1 : + return "unknown symbol"; + case Scanner.ScanSymbols.assign1 : + return "assignment"; + case Scanner.ScanSymbols.if1 : + return "if"; + case Scanner.ScanSymbols.while1 : + return "while"; + case Scanner.ScanSymbols.then1 : + return "then"; + case Scanner.ScanSymbols.else1 : + return "else"; + case Scanner.ScanSymbols.goto1 : + return "goto"; + case Scanner.ScanSymbols.equal1 : + return "="; + case Scanner.ScanSymbols.equalequal1 : + return "=="; + case Scanner.ScanSymbols.less1 : + return "<"; + case Scanner.ScanSymbols.lessequal1 : + return "<="; + case Scanner.ScanSymbols.greater1 : + return ">"; + case Scanner.ScanSymbols.greaterequal1 : + return ">="; + case Scanner.ScanSymbols.notequal1 : + return "<>"; + case Scanner.ScanSymbols.variable1 : + return "variable"; + case Scanner.ScanSymbols.asterisk1 : + return "*"; + case Scanner.ScanSymbols.apostrophe1 : + return "'"; + case Scanner.ScanSymbols.comma1 : + return ","; + case Scanner.ScanSymbols.label1 : + return "label"; + case Scanner.ScanSymbols.literal1 : + return "'"; + case Scanner.ScanSymbols.leftcurly1 : + return "{"; + case Scanner.ScanSymbols.rightcurly1 : + return "}"; + case Scanner.ScanSymbols.leftbracket1 : + return "["; + case Scanner.ScanSymbols.rightbracket1 : + return "]"; + case Scanner.ScanSymbols.numeral1 : + return "numeral"; + case Scanner.ScanSymbols.char1 : + return "character"; + case Scanner.ScanSymbols.divide1 : + return "/"; + case Scanner.ScanSymbols.plus1 : + return "+"; + case Scanner.ScanSymbols.minus1 : + return "-"; + case Scanner.ScanSymbols.leftparen1 : + return "("; + case Scanner.ScanSymbols.rightparen1 : + return ")"; + case Scanner.ScanSymbols.newline1 : + return "newline"; + case Scanner.ScanSymbols.semicolon1 : + return ";"; + case Scanner.ScanSymbols.endtext1 : + return ";"; + case Scanner.ScanSymbols.end1 : + return "end"; + case Scanner.ScanSymbols.andand1 : + return "&&"; + case Scanner.ScanSymbols.oror1 : + return "||"; + case Scanner.ScanSymbols.abs1 : + return "abs"; + case Scanner.ScanSymbols.pow1 : + return "pow"; + case Scanner.ScanSymbols.sqrt1 : + return "sqrt"; + case Scanner.ScanSymbols.not1 : + return "!"; + case Scanner.ScanSymbols.convert1 : + return "convert"; + case Scanner.ScanSymbols.in1 : + return "in"; + case Scanner.ScanSymbols.like1 : + return "like"; + case Scanner.ScanSymbols.trim1 : + return "trim"; + case Scanner.ScanSymbols.upper1 : + return "upper"; + case Scanner.ScanSymbols.lower1 : + return "lower"; + case Scanner.ScanSymbols.substring1 : + return "substring"; + case Scanner.ScanSymbols.getprice1 : + return "getprice"; + case Scanner.ScanSymbols.null1 : + return "null"; + case Scanner.ScanSymbols.isnull1 : + return "isnull"; + default : + return ""; + } + } + public static String SymbolToString(Scanner.ScanSymbols code) + { + switch(code) + { + case Scanner.ScanSymbols.directive_clear_modified1 : + return "directive_clear_modified1"; + case Scanner.ScanSymbols.declare1 : + return "declare1"; + case Scanner.ScanSymbols.unknown1 : + return "unknown1"; + case Scanner.ScanSymbols.assign1 : + return "assign1"; + case Scanner.ScanSymbols.if1 : + return "if1"; + case Scanner.ScanSymbols.while1 : + return "while1"; + case Scanner.ScanSymbols.then1 : + return "then1"; + case Scanner.ScanSymbols.else1 : + return "else1"; + case Scanner.ScanSymbols.goto1 : + return "goto1"; + case Scanner.ScanSymbols.equal1 : + return "equal1"; + case Scanner.ScanSymbols.equalequal1 : + return "equalequal1"; + case Scanner.ScanSymbols.less1 : + return "less1"; + case Scanner.ScanSymbols.lessequal1 : + return "lessequal1"; + case Scanner.ScanSymbols.greater1 : + return "greater1"; + case Scanner.ScanSymbols.greaterequal1 : + return "greaterequal1"; + case Scanner.ScanSymbols.notequal1 : + return "notequal1"; + case Scanner.ScanSymbols.variable1 : + return "variable1"; + case Scanner.ScanSymbols.asterisk1 : + return "asterisk1"; + case Scanner.ScanSymbols.apostrophe1 : + return "apostrophe1"; + case Scanner.ScanSymbols.comma1 : + return "comma1"; + case Scanner.ScanSymbols.label1 : + return "label1"; + case Scanner.ScanSymbols.literal1 : + return "literal1"; + case Scanner.ScanSymbols.leftcurly1 : + return "leftcurly1"; + case Scanner.ScanSymbols.rightcurly1 : + return "rightcurly1"; + case Scanner.ScanSymbols.leftbracket1 : + return "leftbracket1"; + case Scanner.ScanSymbols.rightbracket1 : + return "rightbracket1"; + case Scanner.ScanSymbols.numeral1 : + return "numeral1"; + case Scanner.ScanSymbols.char1 : + return "char1"; + case Scanner.ScanSymbols.divide1 : + return "divide1"; + case Scanner.ScanSymbols.plus1 : + return "plus1"; + case Scanner.ScanSymbols.minus1 : + return "minus1"; + case Scanner.ScanSymbols.leftparen1 : + return "leftparen1"; + case Scanner.ScanSymbols.rightparen1 : + return "rightparen1"; + case Scanner.ScanSymbols.newline1 : + return "newline1"; + case Scanner.ScanSymbols.semicolon1 : + return "semicolon1"; + case Scanner.ScanSymbols.endtext1 : + return "endtext1"; + case Scanner.ScanSymbols.end1 : + return "end1"; + case Scanner.ScanSymbols.andand1 : + return "andand1"; + case Scanner.ScanSymbols.oror1 : + return "oror1"; + case Scanner.ScanSymbols.abs1 : + return "abs1"; + case Scanner.ScanSymbols.pow1 : + return "pow1"; + case Scanner.ScanSymbols.sqrt1 : + return "sqrt1"; + case Scanner.ScanSymbols.not1 : + return "not1"; + case Scanner.ScanSymbols.convert1 : + return "convert1"; + case Scanner.ScanSymbols.in1 : + return "in1"; + case Scanner.ScanSymbols.like1 : + return "like1"; + case Scanner.ScanSymbols.trim1 : + return "trim1"; + case Scanner.ScanSymbols.upper1 : + return "upper1"; + case Scanner.ScanSymbols.lower1 : + return "lower1"; + case Scanner.ScanSymbols.substring1 : + return "substring1"; + case Scanner.ScanSymbols.getprice1 : + return "getprice1"; + case Scanner.ScanSymbols.null1 : + return "null1"; + case Scanner.ScanSymbols.isnull1 : + return "isnull1"; + default : + return ""; + } + } + } +} diff --git a/Axiom.Core/Interpreter/StackElement.cs b/Axiom.Core/Interpreter/StackElement.cs new file mode 100644 index 0000000..8230f2e --- /dev/null +++ b/Axiom.Core/Interpreter/StackElement.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +// FileName : StackElement.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class CodeStack + { + private Stack codeStack = new Stack(); + public CodeStack() + { + } + public void Push(StackElement stackElement) + { + codeStack.Push(stackElement); + } + public StackElement Pop() + { + return codeStack.Pop(); + } + } + public class StackElement + { + public StackElement() + { + } + public GenericData Value { get; set; } + public Symbol Symbol { get; set; } + } +} diff --git a/Axiom.Core/Interpreter/Symbol.cs b/Axiom.Core/Interpreter/Symbol.cs new file mode 100644 index 0000000..bb00664 --- /dev/null +++ b/Axiom.Core/Interpreter/Symbol.cs @@ -0,0 +1,40 @@ +using System; + +// FileName : Symbol.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class Symbol + { + public enum SymbolType { KeywordSymbol,FunctionSymbol, UserSymbol, UserDynamicSymbol, DirectiveSymbol}; + private bool isMutable=true; + private bool isModified=false; + public Symbol() + { + IsMutable = true; + } + public Symbol(String symbolName, Scanner.ScanSymbols identifier,SymbolType symbolType = SymbolType.UserSymbol) + { + this.SymbolName = symbolName; + this.Identifier = identifier; + this.TypeOfSymbol = symbolType; + if (symbolType.Equals(SymbolType.UserSymbol)) IsMutable = true; + else IsMutable = false; + } + public String SymbolName{get;set;} + public Scanner.ScanSymbols Identifier{get;set;} + public SymbolType TypeOfSymbol{get;set;} + public GenericData GenericData { get; set; } + public bool IsMutable + { + get { return isMutable; } + set {isMutable=value;} + } + public bool IsModified + { + get {return isModified;} + set {isModified=value;} + } + } +} diff --git a/Axiom.Core/Interpreter/SymbolTable.cs b/Axiom.Core/Interpreter/SymbolTable.cs new file mode 100644 index 0000000..0855668 --- /dev/null +++ b/Axiom.Core/Interpreter/SymbolTable.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Data; +using log4net; +using System.Reflection; +using Axiom.Utils; + +// FileName : SymbolTable.cs +// Author : Sean Kessler + +namespace Axiom.Interpreter +{ + public class SymbolTable : Dictionary + { + private static ILog logger = LogManager.GetLogger(typeof(SymbolTable)); + private Dictionary symbolsById = new Dictionary(); + public SymbolTable() + { + CreateSymbolTable(); + } +// Example: symbolTable.AddObjects(new Object[]{position}.ToList()); + public void AddObjects(List objects) + { + foreach(Object obj in objects) + { + AddObject(obj); + } + } +// Example: symbolTable.AddObject("Num",55.00); + public void AddObject(String symbolName,Object obj) + { + Type objectType=obj.GetType(); + Symbol symbol=new Symbol(symbolName,Scanner.ScanSymbols.variable1,Symbol.SymbolType.UserSymbol); + Add(symbolName,symbol); + symbol.GenericData = new GenericData(); + String stringRepData = obj.ToString(); + symbol.GenericData.Data = GenericData.ConvertType(objectType, stringRepData); + } +// Example: symbolTable.AddObject(position) + public void AddObject(Object obj) + { + DataTable dataTable=new DataTable(); + Type classType=obj.GetType(); + PropertyInfo[] properties = classType.GetProperties(); + foreach(PropertyInfo propertyInfo in properties) + { + MethodInfo methodInfo=propertyInfo.GetGetMethod(); + String methodName=methodInfo.Name; + if(!methodName.StartsWith("get_"))continue; + methodName=methodName.Replace("get_",null); + DataColumn dataColumn=new DataColumn(); + dataColumn.ColumnName=methodName; + dataColumn.DataType=methodInfo.ReturnType; // capture the data type + dataTable.Columns.Add(dataColumn); + } + DataRow dataRow=dataTable.NewRow(); + foreach(PropertyInfo propertyInfo in properties) + { + MethodInfo methodInfo=propertyInfo.GetGetMethod(); + String methodName=methodInfo.Name; + if(!methodName.StartsWith("get_"))continue; + methodName=methodName.Replace("get_",null); + dataRow[methodName]=methodInfo.Invoke(obj,null); + } + AddUserSymbols(dataTable); + AddUserValues(dataRow,dataTable); + } + public void AddUserSymbols(DataTable dataTable) + { + DataColumnCollection columns=dataTable.Columns; + foreach (DataColumn column in columns) + { + String symbolName = column.ColumnName; + if(ContainsKey(symbolName))continue; + Symbol symbol=new Symbol(symbolName,Scanner.ScanSymbols.variable1,Symbol.SymbolType.UserSymbol); + Add(symbolName,symbol); + } + } + public void AddUserValues(DataRow dataRow,DataTable dataTable) + { + DataColumnCollection columns = dataTable.Columns; + for(int index=0;index GetModfied() + { + List symbols = this.Values.ToList(); + symbols = (from Symbol symbol in symbols where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserSymbol) && symbol.IsModified select symbol).ToList(); + return symbols; + } + public String GetModifiedSymbolNames() + { + List symbols = this.Values.ToList(); + List symbolNames = (from Symbol symbol in symbols where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserSymbol) && symbol.IsModified select symbol.SymbolName).ToList(); + return Utility.ListToString(symbolNames); + } + public void Reset() + { + ClearModified(); + ClearData(); + RemoveUserDynamicSymbols(); + } + public void RemoveUserDynamicSymbols() + { + List symbols = this.Values.ToList(); + symbols = (from Symbol symbol in symbols where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserDynamicSymbol) select symbol).ToList(); + foreach (Symbol symbol in symbols) this.Remove(symbol.SymbolName); + } + public void ClearModified() + { + List symbols = this.Values.ToList(); + symbols = (from Symbol symbol in symbols where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserSymbol) select symbol).ToList(); + foreach (Symbol symbol in symbols) symbol.IsModified = false; + } + public void ClearData() + { + List symbols = this.Values.ToList(); + foreach (Symbol symbol in symbols) symbol.GenericData = null; + } + public bool IsModified() + { + List symbols = this.Values.ToList(); + symbols = (from Symbol symbol in symbols where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserSymbol) select symbol).ToList(); + foreach (Symbol symbol in symbols) if(symbol.IsModified)return true; + return false; + } + private void CreateSymbolTable() + { + Add("#directive_clear_modified",new Symbol("#directive_clear_modified",Scanner.ScanSymbols.directive_clear_modified1,Symbol.SymbolType.DirectiveSymbol)); + Add("declare",new Symbol("declare",Scanner.ScanSymbols.declare1,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("while",new Symbol("while",Scanner.ScanSymbols.while1,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)); + Add("or", new Symbol("or", Scanner.ScanSymbols.oror1, Symbol.SymbolType.KeywordSymbol)); + Add("null", new Symbol("null", Scanner.ScanSymbols.null1, Symbol.SymbolType.KeywordSymbol)); +// high level functions + Symbol symbol=null; + + symbol=new Symbol("abs", Scanner.ScanSymbols.abs1, Symbol.SymbolType.FunctionSymbol); // abs(x) + Add("abs",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.abs1,symbol); + + symbol=new Symbol("pow", Scanner.ScanSymbols.pow1, Symbol.SymbolType.FunctionSymbol); // pow(x,y) + Add("pow",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.pow1,symbol); + + symbol=new Symbol("sqrt", Scanner.ScanSymbols.sqrt1, Symbol.SymbolType.FunctionSymbol); // sqrt(x) + Add("sqrt",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.sqrt1,symbol); + + symbol=new Symbol("convert", Scanner.ScanSymbols.convert1, Symbol.SymbolType.FunctionSymbol); // convert(x,'{type}') convert(variable|literal,'{datatype}') convert('01-02-2018','System.DateTime') + Add("convert",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.convert1,symbol); + + symbol=new Symbol("substring", Scanner.ScanSymbols.substring1, Symbol.SymbolType.FunctionSymbol); // substring(variable|literal,numeral|variable,numeral|variable) + Add("substring",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.substring1,symbol); + + symbol=new Symbol("getprice", Scanner.ScanSymbols.getprice1, Symbol.SymbolType.FunctionSymbol); // getprice(variable|literal,variable|literal) getprice('midd','07-12-2021') + Add("getprice",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.getprice1,symbol); + + symbol=new Symbol("in", Scanner.ScanSymbols.in1, Symbol.SymbolType.FunctionSymbol); // in('X','Y','Z') + Add("in",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.in1,symbol); + + symbol=new Symbol("like", Scanner.ScanSymbols.like1, Symbol.SymbolType.FunctionSymbol); // like 'x%' + Add("like",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.like1,symbol); + + symbol=new Symbol("trim", Scanner.ScanSymbols.trim1, Symbol.SymbolType.FunctionSymbol); // trim('x') + Add("trim",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.trim1,symbol); + + symbol=new Symbol("upper", Scanner.ScanSymbols.upper1, Symbol.SymbolType.FunctionSymbol); // upper('x') + Add("upper",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.upper1,symbol); + + symbol=new Symbol("lower", Scanner.ScanSymbols.lower1, Symbol.SymbolType.FunctionSymbol); // lower('x') + Add("lower",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.lower1,symbol); + + symbol=new Symbol("isnull", Scanner.ScanSymbols.isnull1, Symbol.SymbolType.FunctionSymbol); // isnull(variable) + Add("isnull",symbol); + symbolsById.Add((int)Scanner.ScanSymbols.isnull1,symbol); + } + public Symbol Find(Scanner.ScanSymbols identifier) + { + if (!symbolsById.ContainsKey((int)identifier)) return null; + return this[symbolsById[(int)identifier].SymbolName]; + } + } +} diff --git a/Axiom.Core/Utility/Utility.cs b/Axiom.Core/Utility/Utility.cs new file mode 100644 index 0000000..1f0e9ae --- /dev/null +++ b/Axiom.Core/Utility/Utility.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Globalization; +using log4net; + +namespace Axiom.Utils +{ + public class Utility + { + private static ILog logger = LogManager.GetLogger(typeof(Utility)); + private Utility() + { + } + public static Stream StreamFromString(string s) + { + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); + writer.Write(s); + writer.Flush(); + stream.Position = 0; + return stream; + } + public static String ListToString(List list) + { + if (null == list || 0 == list.Count) return ""; + StringBuilder sb = new StringBuilder(); + for (int index = 0; index < list.Count; index++) + { + sb.Append(list[index]); + if (index < list.Count-1) sb.Append(","); + } + return sb.ToString(); + } + public static String DateTimeToStringYYYYMMDD(DateTime dateTime) + { + return dateTime.ToString("yyyyMMdd"); + } + public static String DateTimeToStringMMHDDHYYYY(DateTime dateTime) + { + return dateTime.ToString("MM-dd-yyyy"); + } + public static String DateTimeToStringMMSDDSYYYYHHMMSS(DateTime dateTime) + { + return dateTime.ToString("MM/dd/yyyy hh:mm:ss tt"); + } + public static String DateTimeToTicks(DateTime dateTime) + { + return dateTime.Ticks.ToString(); + } + public static String KeepAfter(String strString,char ch) + { + int startPos = strString.IndexOf(ch); + if (-1 == startPos) return strString; + return strString.Substring(startPos + 1); + } + public static String KeepBefore(String strString, char ch) + { + int startPos = strString.IndexOf(ch); + if (-1 == startPos) return strString; + return strString.Substring(0,startPos); + } + public static DateTime ParseDate(String strDate) + { + logger.InfoFormat("Parsing date {0}",strDate); + System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-US"); + String[] formats = new[] { "yyyy/MM/dd","M-d-yyyy", "dd-MM-yyyy", "MM-dd-yyyy", "M.d.yyyy", "dd.MM.yyyy", "MM.dd.yyyy","yyyyMMdd" }.Union(cultureInfo.DateTimeFormat.GetAllDateTimePatterns()).ToArray(); + strDate = strDate.Trim(); + DateTime dateTime=DateTime.ParseExact(strDate, formats, new System.Globalization.CultureInfo("en-US"), DateTimeStyles.AssumeLocal); + return dateTime; + } + public static String AddQuotes(String item) + { + return "\"" + item + "\""; + } + public static String RemoveCC(String item) + { + StringBuilder sb = new StringBuilder(); + foreach (char ch in item) + { + if (!Char.IsControl(ch)) sb.Append(ch); + } + return sb.ToString(); + } + public static String SqlString(String value) + { + StringBuilder sb = new StringBuilder(); + foreach (char ch in value) + { + sb.Append(ch); + if (ch == '\'') sb.Append("'"); + } + return sb.ToString(); + } + public static String IsNull(String s1,String s2) + { + if (null == s1) return s2; + return s1; + } + public static String NullIfOrCat(String s1,String s2,String s3) + { + if (string.IsNullOrEmpty(s1)) return s2; + return s1+s3; + } + public static String Pad(string str, char filler, int length) + { + int stringLength = str.Length; + if (stringLength >= length) return str; + StringBuilder sb = new StringBuilder(); + + while (stringLength < length) + { + sb.Append(filler); + stringLength++; + } + return sb.ToString() + str; + } + public static String CreateInClause(String commaSepList,String dataType) + { + StringBuilder sb = new StringBuilder(); + sb.Append("("); + String[] items = commaSepList.Split(','); + for (int index = 0; index < items.Length; index++) + { + sb.Append("'").Append(items[index]).Append("'"); + if (index < items.Length - 1) sb.Append(","); + } + sb.Append(")"); + return sb.ToString(); + } + } +} diff --git a/Axiom.Core/app.config b/Axiom.Core/app.config new file mode 100644 index 0000000..43ee139 --- /dev/null +++ b/Axiom.Core/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Axiom.sln b/Axiom.sln new file mode 100644 index 0000000..1606567 --- /dev/null +++ b/Axiom.sln @@ -0,0 +1,29 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Axiom.Core", "Axiom.Core\Axiom.Core.csproj", "{F0F0F2B4-BB86-49B5-BA93-2642637033D6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{88CECEDC-E4EE-4E86-8FE0-B670FA5C710F}" + ProjectSection(SolutionItems) = preProject + Notes.txt = Notes.txt + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C0AFCD8E-4455-40BA-BE0B-79C0C85CC83D} + EndGlobalSection +EndGlobal diff --git a/AxiomConsole.sln b/AxiomConsole.sln new file mode 100644 index 0000000..f48fe52 --- /dev/null +++ b/AxiomConsole.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Axiom.Core", "Axiom.Core\Axiom.Core.csproj", "{F0F0F2B4-BB86-49B5-BA93-2642637033D6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AxiomConsole", "AxiomConsole\AxiomConsole.csproj", "{33E3DF62-2592-4040-B858-F8D115686531}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Release|Any CPU.Build.0 = Release|Any CPU + {33E3DF62-2592-4040-B858-F8D115686531}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33E3DF62-2592-4040-B858-F8D115686531}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33E3DF62-2592-4040-B858-F8D115686531}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33E3DF62-2592-4040-B858-F8D115686531}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C0AFCD8E-4455-40BA-BE0B-79C0C85CC83D} + EndGlobalSection +EndGlobal diff --git a/AxiomConsole/App.config b/AxiomConsole/App.config new file mode 100644 index 0000000..8d23437 --- /dev/null +++ b/AxiomConsole/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/AxiomConsole/AxiomConsole.csproj b/AxiomConsole/AxiomConsole.csproj new file mode 100644 index 0000000..b557efe --- /dev/null +++ b/AxiomConsole/AxiomConsole.csproj @@ -0,0 +1,66 @@ + + + + + Debug + AnyCPU + {33E3DF62-2592-4040-B858-F8D115686531} + Exe + Properties + AxiomConsole + AxiomConsole + v4.6.2 + 512 + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + {f0f0f2b4-bb86-49b5-ba93-2642637033d6} + Axiom.Core + + + + + \ No newline at end of file diff --git a/AxiomConsole/AxiomConsole.sln b/AxiomConsole/AxiomConsole.sln new file mode 100644 index 0000000..a31dab7 --- /dev/null +++ b/AxiomConsole/AxiomConsole.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AxiomConsole", "AxiomConsole.csproj", "{33E3DF62-2592-4040-B858-F8D115686531}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Axiom.Core", "..\Axiom.Core\Axiom.Core.csproj", "{F0F0F2B4-BB86-49B5-BA93-2642637033D6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {33E3DF62-2592-4040-B858-F8D115686531}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33E3DF62-2592-4040-B858-F8D115686531}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33E3DF62-2592-4040-B858-F8D115686531}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33E3DF62-2592-4040-B858-F8D115686531}.Release|Any CPU.Build.0 = Release|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AxiomConsole/Program.cs b/AxiomConsole/Program.cs new file mode 100644 index 0000000..408b681 --- /dev/null +++ b/AxiomConsole/Program.cs @@ -0,0 +1,52 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using Axiom.Utils; +using Axiom.Interpreter; +using System.IO; + +namespace AxiomConsole +{ + class Program + { + static void Main(string[] args) + { + +// String expression=@" +// A=1; +// WHILE(A<10) +// { +// IF(A==1)THEN break; +// }"; + String expression=@" + A=1; + B=1; + WHILE(A<10) + { + WHILE(B<10) + { + IF(B==1)THEN BREAK; + B=B+1; + } + IF(A==1)THEN BREAK; + A=A+1; + }"; + CodeRunner codeRunner=new CodeRunner(); + List 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(); + } + } +} + diff --git a/AxiomConsole/Properties/AssemblyInfo.cs b/AxiomConsole/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f605028 --- /dev/null +++ b/AxiomConsole/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AxiomConsole")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AxiomConsole")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("650e4f18-bbd4-400b-b445-5c497023c280")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AxiomUnitTestProject/AxiomUnitTestProject.sln b/AxiomUnitTestProject/AxiomUnitTestProject.sln new file mode 100644 index 0000000..3646c19 --- /dev/null +++ b/AxiomUnitTestProject/AxiomUnitTestProject.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AxiomUnitTestProject", "AxiomUnitTestProjectr\AxiomUnitTestProject.csproj", "{E2FC10FA-2B8A-4CEB-B7C6-960FA6A3AC6F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Axiom.Core", "..\Axiom.Core\Axiom.Core.csproj", "{F0F0F2B4-BB86-49B5-BA93-2642637033D6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E2FC10FA-2B8A-4CEB-B7C6-960FA6A3AC6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2FC10FA-2B8A-4CEB-B7C6-960FA6A3AC6F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2FC10FA-2B8A-4CEB-B7C6-960FA6A3AC6F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2FC10FA-2B8A-4CEB-B7C6-960FA6A3AC6F}.Release|Any CPU.Build.0 = Release|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0F0F2B4-BB86-49B5-BA93-2642637033D6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AxiomUnitTestProject/AxiomUnitTestProjectr/App.config b/AxiomUnitTestProject/AxiomUnitTestProjectr/App.config new file mode 100644 index 0000000..84cda96 --- /dev/null +++ b/AxiomUnitTestProject/AxiomUnitTestProjectr/App.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/AxiomUnitTestProject/AxiomUnitTestProjectr/AssemblerTests.cs b/AxiomUnitTestProject/AxiomUnitTestProjectr/AssemblerTests.cs new file mode 100644 index 0000000..930c887 --- /dev/null +++ b/AxiomUnitTestProject/AxiomUnitTestProjectr/AssemblerTests.cs @@ -0,0 +1,736 @@ +using System; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using Axiom.Utils; +using Axiom.Interpreter; +using System.IO; + +namespace AxiomUnitTestProject +{ + + [TestClass] + public class AssemblerTests + { + [TestMethod] + public void BreakStatementVariant4() + { + String expression=@" + A=1; + B=1; + WHILE(A<10) + { + WHILE(B<10) + { + IF(B==100)THEN BREAK; + B=B+1; + } + IF(A==100)THEN BREAK; + A=A+1; + }"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("A").Equals(10)); + Assert.IsTrue(codeRunner.GetValue("B").Equals(10)); + } + + [TestMethod] + public void BreakStatementVariant3() + { + String expression=@" + A=1; + B=1; + WHILE(A<10) + { + WHILE(B<10) + { + IF(B==1)THEN BREAK; + B=B+1; + } + IF(A==1)THEN BREAK; + A=A+1; + }"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("A").Equals(1)); + Assert.IsTrue(codeRunner.GetValue("B").Equals(1)); + } + + [TestMethod] + public void BreakStatementVariant2() + { + String expression=@" + A=1; + WHILE(A<10) + { + IF(A==1)THEN BREAK; + A=A+1; + } + "; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("A").Equals(1)); + } + + [TestMethod] + public void BreakStatementVariant1() + { + String expression=@" + break; + "; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsFalse(codeRunner.Execute(expression),codeRunner.LastMessage); + } + + [TestMethod] + public void DeclarationStatementVariant3() + { + String expression=@" + DECLARE A; + DECLARE B; + B=5; + DECLARE C; + D=6; + "; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("D").Equals(6)); + } + + [TestMethod] + public void DeclarationStatementVariant2() + { + String expression=@" + DECLARE A; + DECLARE B; + B=5; + DECLARE C; + "; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("B").Equals(5)); + } + + [TestMethod] + public void DeclarationStatementVariant1() + { + String expression=@" + DECLARE A; + DECLARE B; + B=5; + "; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("B").Equals(5)); + } + + [TestMethod] + public void WhileStatementVariant4() + { + String expression=@" + DECLARE A,B; + A=1; + B=5; + ITERATIONS=0; + WHILE(A<=10) + { + B=1; + WHILE(B<=5) + { + B=B+1; + ITERATIONS=ITERATIONS+1; + } + A=A+1; + }"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("A").Equals(11)); + Assert.IsTrue(codeRunner.GetValue("ITERATIONS").Equals(50)); + } + + [TestMethod] + public void WhileStatementVariant3() + { + String expression=@" + DECLARE A,B; + A=1; + B=5; + WHILE(A("A").Equals(5)); + } + + [TestMethod] + public void WhileStatementVariant2() + { + String expression="DECLARE A,B;A=1;B=5;WHILE(A("A").Equals(5)); + } + + [TestMethod] + public void WhileStatementVariant1() + { + String expression="DECLARE A,B;A=1;B=5;WHILE(A("A").Equals(5)); + } + + [TestMethod] + public void DeclarationsVariant4() + { + String expression="DECLARE R,user_a,user_b,user_c;R=7;user_a=66;user_b=66;user_c=66;IF(R>=5){user_a=1;user_b=1;user_c=1;}"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + } + + [TestMethod] + public void DeclarationsVariant3() + { + String expression="DECLARE VAR1,VAR1;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsFalse(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.LastMessage.Contains("The variable 'VAR1' has already been declared.")); + } + + [TestMethod] + public void DeclarationsVariant2() + { + String expression="DECLARE VAR1,VAR2;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + } + + [TestMethod] + public void DeclarationsVariant1() + { + String expression="DECLARE VAR1;DECLARE VAR2;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + } + + [TestMethod] + public void LowerCall() + { + String expression="DECLARE VAR1;VAR1='Hello ';VAR1=TRIM(VAR1);VAR1=LOWER(VAR1);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("VAR1").Equals("hello")); + } + + [TestMethod] + public void UpperCall() + { + String expression="DECLARE VAR1;VAR1='Hello ';VAR1=TRIM(VAR1);VAR1=UPPER(VAR1);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("VAR1").Equals("HELLO")); + } + + [TestMethod] + public void TrimCall() + { + String expression="DECLARE VAR1;VAR1='Hello ';VAR1=TRIM(VAR1);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("VAR1").Equals("Hello")); + } + + [TestMethod] + public void IfStatementVariant20() + { + // There is a missing right paren in the if statement nesting so we expect a syntax error + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=1;IF((((((VAR1=='YES'))))) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsFalse(codeRunner.Execute(expression)); + Assert.IsTrue(codeRunner.LastMessage.Contains("")); + } + + [TestMethod] + public void IfStatementVariant19() + { + String expression = "DECLARE a,b;a=1;b=1;IF(1+1)upper('Foo');"; + CodeRunner codeRunner=new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.ParseSymbolsCount.Equals(0),"Expected parse symbols count to be zero."); + } + + [TestMethod] + public void IfStatementVariant18() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1=2;IF(VAR1==2) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("TRUE")); + } + + [TestMethod] + public void IfStatementVariant17() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=1;IF(VAR1=='YES') THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("TRUE")); + } + + [TestMethod] + public void IfStatementVariant16() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=1;IF((((((VAR1=='YES')))))) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("TRUE")); + } + + [TestMethod] + public void IfStatementVariant15() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF((VAR1=='YES') AND VAR2=='NO') THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("FALSE")); + } + + [TestMethod] + public void IfStatementVariant14() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=2;IF(VAR1=='YES' AND (VAR2=='YES') AND VAR4==1) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("FALSE")); + } + + [TestMethod] + public void IfStatementVariant13() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF(VAR1=='YES' AND (VAR2=='YES') AND VAR4==1) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("TRUE")); + } + + [TestMethod] + public void IfStatementVariant12() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF((VAR1=='YES') OR (VAR2=='YES') AND (VAR4==1)) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("TRUE")); + } + + [TestMethod] + public void IfStatementVariant11() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='NO';VAR2='YES';VAR4=1;IF(VAR1=='YES' OR VAR2=='YES' AND VAR4==2) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("FALSE")); + } + + [TestMethod] + public void IfStatementVariant10() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF(VAR1=='YES' OR VAR2=='YES' AND VAR4==2) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("TRUE")); + } + + [TestMethod] + public void IfStatementVariant9() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=2;IF(VAR1=='NO' OR (VAR2=='YES' AND VAR4==1)) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("FALSE")); + } + + [TestMethod] + public void IfStatementVariant8() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF(VAR1=='NO' OR (VAR2=='YES' AND VAR4==1)) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("TRUE")); + } + + [TestMethod] + public void IfStatementVariant7() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=2;IF((VAR1=='YES') AND VAR2=='NO' AND VAR4==1) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("FALSE")); + } + + [TestMethod] + public void IfStatementVariant6() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=1;IF((VAR1=='YES') AND VAR2=='NO' AND VAR4==1) THEN RESULT='TRUE' ELSE RESULT='FALSE';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("TRUE")); + } + + [TestMethod] + public void IfStatementVariant5() + { + String expression="DECLARE A,B,RESULT;A=1;B=2;IF(A==1 AND B==2)THEN RESULT=1 ELSE RESULT=0;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals(1.00)); + } + + [TestMethod] + public void IfStatementVariant4() + { + String expression="DECLARE A,B;A=99;if(A<>99)then B=1 else B=2;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("B").Equals(2.00)); + } + + [TestMethod] + public void IfStatementVariant3() + { + String expression="DECLARE R,user_a,user_b,user_c;R=7;user_a=66;user_b=66;user_c=66;IF(R>=5){user_a=1;user_b=1;user_c=1;}"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("user_a").Equals(1.00)); + Assert.IsTrue(codeRunner.GetValue("user_b").Equals(1.00)); + Assert.IsTrue(codeRunner.GetValue("user_c").Equals(1.00)); + } + + [TestMethod] + public void IfStatementVariant2() + { + String expression="DECLARE A,B,C;A=1;B=2;C=3;IF(B("A").Equals(1.00)); + Assert.IsTrue(codeRunner.GetValue("B").Equals(1.00)); + Assert.IsTrue(codeRunner.GetValue("C").Equals(1.00)); + } + + [TestMethod] + public void IfStatementVariant1() + { + String expression="R_THRESHHOLD=4;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + double b = codeRunner.GetValue("R_THRESHHOLD"); + Assert.IsTrue(b.Equals(4.00)); + } + + private class InjectionClass + { + public double RMultiple { get { return (CurrentPrice-PurchasePrice)/R; } } + public double CurrentPrice{ get; set; } + public double PurchasePrice{ get; set; } + public double R { get; set; } + } + + [TestMethod] + public void Injection() + { + String expression=@" + R_THRESHHOLD=4; + MAX_ATR=3; + MAX_R=10; + FACTOR=MAX_ATR/MAX_R; + MULTIPLIER=MAX_ATR; + IF(RMultiple>R_THRESHHOLD) + { + MULTIPLIER=FACTOR*RMultiple; + }"; + + InjectionClass injectionClass = new InjectionClass(); + injectionClass.CurrentPrice=220; + injectionClass.PurchasePrice=195.90; + injectionClass.R=5.00; + + CodeRunner codeRunner = new CodeRunner(); + SymbolTable symbolTable=codeRunner.SymbolTable; + symbolTable.AddObjects(new Object[]{injectionClass}.ToList()); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("MULTIPLIER").Equals(1.446)); + } + + [TestMethod] + public void Substring() + { + String expression="DECLARE CURRENCY,START_INDEX,LENGTH,CURRENCY_CODE;CURRENCY='MXN12345';START_INDEX=1;LENGTH=3;CURRENCY_CODE=SUBSTRING(CURRENCY,START_INDEX,LENGTH);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("CURRENCY_CODE").Equals("MXN")); + } + + [TestMethod] + public void InStatement() + { + String expression="DECLARE CURRENCY,A;CURRENCY='MXN';A=CURRENCY in('USD','JPY');"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("A").Equals(false)); + } + + [TestMethod] + public void InStatement2() + { + String expression="DECLARE CURRENCY,A;CURRENCY='MXN';A=CURRENCY in('USD','JPY','MXN');"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("A").Equals(true)); + } + + [TestMethod] + public void NestedParens() + { + String expression="DECLARE A,B,C;A=100/50;B=100-(((2*2)*8)*9);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("B").Equals(-188)); + } + + [TestMethod] + public void Power() + { + String expression="DECLARE A,B,C;A=100;B=.5;C=pow(A,B);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("C").Equals(10)); + } + + [TestMethod] + public void OrderOfOperations() + { + String expression="DECLARE NUM1;NUM1=3*4*(2+1)"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("NUM1").Equals(36)); + } + + [TestMethod] + public void NumericalEquality() + { + String expression="DECLARE NOTIONAL,DELTA,DELTA_ADJUSTED_NOTIONAL;NOTIONAL=20.00;if(2==2)then DELTA=.01 else DELTA=1.00;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("DELTA").Equals(.01)); + } + + [TestMethod] + public void Division() + { + String expression="DECLARE NOTIONAL,DELTA,DELTA_ADJUSTED_NOTIONAL;NOTIONAL=1000.00;DELTA=.25;DELTA_ADJUSTED_NOTIONAL=NOTIONAL/DELTA;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("DELTA_ADJUSTED_NOTIONAL").Equals(4000)); + } + + [TestMethod] + public void Addition() + { + String expression="DECLARE a,b,c;a=100;b=100+a;c=-100;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("b").Equals(200)); + } + + [TestMethod] + public void NullCoalescing() + { + String expression="DECLARE RESULT,A,B,C,D;A=null;B=null;C='NotNull';RESULT=ISNULL(A,B,C);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("NotNull")); + } + + [TestMethod] + public void DateComparisons() + { + String expression="DECLARE RESULT,A,B,C,D;A=CONVERT('01-01-2018','System.DateTime');B=CONVERT('01-02-2018','System.DateTime');IF(A>B) THEN RESULT='01-01-2018 IS GREATER THAN 01-02-2018' ELSE RESULT='01-02-2018 IS GREATER THAN 01-01-2018';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("RESULT").Equals("01-02-2018 IS GREATER THAN 01-01-2018")); + } + + [TestMethod] + public void StringMultiplication() + { + String expression="DECLARE A,B,C;A='45';B='2';C=A*B;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("C").Equals(90.00)); + } + + [TestMethod] + public void ExponentialNotation() + { + String expression="DECLARE OAC;OAC=-3.52E-05;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("OAC").Equals(-3.52E-05)); + } + + + [TestMethod] + public void StringConcatenation() + { + String expression="DECLARE ENTITY_ID,AXIOM_META_TAG;ENTITY_ID=148;IF(ENTITY_ID==148)THEN AXIOM_META_TAG=ENTITY_ID+'_BG' ELSE AXIOM_META_TAG=null;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("AXIOM_META_TAG").Equals("148_BG")); + } + + [TestMethod] + public void StringConcatenation2() + { + String expression="DECLARE A,B,C;A='45';B='2';C=A+B;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("C").Equals("452")); + } + + [TestMethod] + public void StringComparison() + { + String expression="DECLARE ENTITY_ID;ENTITY_ID='';IF(ENTITY_ID=='')THEN ENTITY_ID='ENTITY_ID IS BLANK'ELSE ENTITY_ID='ENTITY_ID IS NOT BLANK';"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("ENTITY_ID").Equals("ENTITY_ID IS BLANK")); + } + + [TestMethod] + public void DateConversion() + { + String expression="DECLARE ENTITY_ID,EFFECTIVE_DATE;ENTITY_ID=null;IF(ENTITY_ID==null)THEN EFFECTIVE_DATE=CONVERT('2/1/2024','System.DateTime');"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("EFFECTIVE_DATE").Equals(new DateTime(2024,2,1))); + } + + [TestMethod] + public void LikeClause() + { + String expression="DECLARE FIN.Securities.IndustryClass4,FIN.Securities.Country,FIN.Securities.ISIN;FIN.Securities.ISIN='ARARGE';IF(FIN.Securities.ISIN LIKE 'ARARGE'){FIN.Securities.IndustryClass4 = 'Treasury Bond';FIN.Securities.Country='USD'};"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("FIN.Securities.IndustryClass4").Equals("Treasury Bond")); + Assert.IsTrue(codeRunner.GetValue("FIN.Securities.Country").Equals("USD")); + } + + [TestMethod] + public void AbsoluteValueVariant2() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1=-1;VAR2=-3;VAR2=ABS(VAR2)+1;"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("VAR2").Equals(4)); + } + + [TestMethod] + public void AbsoluteValueVariant1() + { + String expression="DECLARE VAR1,VAR2,VAR4,RESULT;VAR1=((ABS(-1)+2)+3);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("VAR1").Equals(6)); + } + + [TestMethod] + public void Multiplication() + { + String expression="DECLARE var1,var2,var3,var4;var1=1;var2=2;var3=3;var4=var1*var2*var3*var1*var2*var3*abs(var1);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("var4").Equals(36.00)); + } + + [TestMethod] + public void AbsoluteValueConvesion() + { + String expression="DECLARE var1,var2,var3,var4;var1=-1;var2=-2;var3=-3;var4=abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2);"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("var4").Equals(4096.00)); + } + + + [TestMethod] + public void StringToDoubleConvesion() + { + String expression="DECLARE var1,var2,var3,var4;var1='2';var2='4';var3='6';var4=CONVERT(var1,'System.Double')*CONVERT(var2,'System.Double')*CONVERT(var3,'System.Double');"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("var1").Equals(2.00)); + } + + [TestMethod] + public void UpperCaseShouldConvert() + { + String expression="DECLARE var1,var2,var3,var4;var1='Hello';var2=' ';var3='World';var4=UPPER(var1)+UPPER(var2)+UPPER(var3)"; + CodeRunner codeRunner = new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.GetValue("var4").Equals("HELLO WORLD")); + } + + [TestMethod] + public void AssembleAllUseCases() + { + foreach(String expression in TestData.CodeLines()) + { + CodeRunner codeRunner= new CodeRunner(); + Assert.IsTrue(codeRunner.Execute(expression),codeRunner.LastMessage); + Assert.IsTrue(codeRunner.ParseSymbolsCount.Equals(0),"Expected parse symbols to be zero."); + } + } + + //[TestMethod] + //public void AssembleAllData() + //{ + // List codeLines=TestData.CodeLines(); + // foreach(String expression in codeLines) + // { + // Console.WriteLine("*********************************************************************************************************************************"); + // BinaryWriter binaryWriter=new BinaryWriter(new MemoryStream()); + // SymbolTable symbolTable = new SymbolTable(); + // BinaryReader binaryReader = null; + // binaryReader = new BinaryReader(Utility.StreamFromString(expression)); + // Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable); + // scanner.Debug=false; + // Console.WriteLine("Expression:\""+expression+"\""); + // Assert.IsTrue(scanner.Analyze()); + // binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin); + // BinaryReader parserReader = new BinaryReader(binaryWriter.BaseStream); + // BinaryWriter parserWriter = new BinaryWriter(new MemoryStream()); + // Parser parser = new Parser(parserReader,parserWriter,symbolTable); + // parser.Debug=false; + // parser.Parse(); + // Assert.IsFalse(parser.IsInError); + // parserWriter.BaseStream.Seek(0, SeekOrigin.Begin); + // BinaryReader assemblerReader = new BinaryReader(parserWriter.BaseStream); + // Assembler assembler = new Assembler(assemblerReader, symbolTable); + // bool result=assembler.Assemble(); + // assembler.Disassemble(); + // Assert.IsTrue(result); + // Console.WriteLine("********************************************************* O U T P U T ************************************************"); + // List list = new List(symbolTable.Values); + // list=(from Symbol symbol in list where (symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserSymbol)||symbol.TypeOfSymbol.Equals(Symbol.SymbolType.UserDynamicSymbol)) && symbol.IsModified select symbol).ToList(); + // foreach (Symbol symbol in list) + // { + // Console.WriteLine(String.Format("SYMBOL NAME:'{0}',VALUE:'{1}'",symbol.SymbolName,null==symbol.GenericData?"":symbol.GenericData.ToString())); + // } + // Console.WriteLine("*********************************************************************************************************************************"); + // assembler.Dispose(); + // } + //} + } +} + diff --git a/AxiomUnitTestProject/AxiomUnitTestProjectr/AxiomUnitTestProject.csproj b/AxiomUnitTestProject/AxiomUnitTestProjectr/AxiomUnitTestProject.csproj new file mode 100644 index 0000000..5759bfc --- /dev/null +++ b/AxiomUnitTestProject/AxiomUnitTestProjectr/AxiomUnitTestProject.csproj @@ -0,0 +1,100 @@ + + + + Debug + AnyCPU + {E2FC10FA-2B8A-4CEB-B7C6-960FA6A3AC6F} + Library + Properties + AxiomUnitTestProjectr + AxiomUnitTestProjectr + v4.6.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\References\MySql.Data.dll + + + + + + + + + + + + + + + + + + + + + + + + + {f0f0f2b4-bb86-49b5-ba93-2642637033d6} + Axiom.Core + + + + + + + + + + False + + + False + + + False + + + False + + + + + + + + \ No newline at end of file diff --git a/AxiomUnitTestProject/AxiomUnitTestProjectr/ParserTests.cs b/AxiomUnitTestProject/AxiomUnitTestProjectr/ParserTests.cs new file mode 100644 index 0000000..662dfb0 --- /dev/null +++ b/AxiomUnitTestProject/AxiomUnitTestProjectr/ParserTests.cs @@ -0,0 +1,37 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using Axiom.Utils; +using Axiom.Interpreter; +using System.IO; + +namespace AxiomUnitTestProject +{ + [TestClass] + public class ParserTests + { + [TestMethod] + public void ParserShouldParseAll() + { + List codeLines = TestData.CodeLines(); + foreach(String expression in codeLines) + { + BinaryWriter binaryWriter=new BinaryWriter(new MemoryStream()); + SymbolTable symbolTable = new SymbolTable(); + BinaryReader binaryReader = null; + binaryReader = new BinaryReader(Utility.StreamFromString(expression)); + Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable); + scanner.Debug=false; + Console.WriteLine("Expression:\""+expression+"\""); + Assert.IsTrue(scanner.Analyze()); + binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin); + BinaryReader parserReader = new BinaryReader(binaryWriter.BaseStream); + BinaryWriter parserWriter = new BinaryWriter(new MemoryStream()); + Parser parser = new Parser(parserReader,parserWriter,symbolTable); + parser.Debug=true; + parser.Parse(); + Assert.IsFalse(parser.IsInError,parser.LastMessage); + } + } + } +} \ No newline at end of file diff --git a/AxiomUnitTestProject/AxiomUnitTestProjectr/Properties/AssemblyInfo.cs b/AxiomUnitTestProject/AxiomUnitTestProjectr/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1a6ab07 --- /dev/null +++ b/AxiomUnitTestProject/AxiomUnitTestProjectr/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AxiomUnitTestProjectr")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AxiomUnitTestProjectr")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d86be38f-cf72-4df8-a28e-c95922ecbadd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AxiomUnitTestProject/AxiomUnitTestProjectr/ScannerTests.cs b/AxiomUnitTestProject/AxiomUnitTestProjectr/ScannerTests.cs new file mode 100644 index 0000000..cacdd9e --- /dev/null +++ b/AxiomUnitTestProject/AxiomUnitTestProjectr/ScannerTests.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using Axiom.Utils; +using Axiom.Interpreter; +using System.IO; + +namespace AxiomUnitTestProject +{ + [TestClass] + public class ScannerTests + { + [TestMethod] + public void ScannerShouldScan() + { + List codeLines = TestData.CodeLines(); + foreach(String expression in codeLines) + { + BinaryWriter binaryWriter=new BinaryWriter(new MemoryStream()); + SymbolTable symbolTable = new SymbolTable(); + BinaryReader binaryReader = null; + binaryReader = new BinaryReader(Utility.StreamFromString(expression)); + Scanner scanner = new Scanner(binaryReader, binaryWriter, symbolTable); + Console.WriteLine("Expression:\""+expression+"\""); + Assert.IsTrue(scanner.Analyze()); + Console.WriteLine("**************************"); + } + } + } +} diff --git a/AxiomUnitTestProject/AxiomUnitTestProjectr/TestData.cs b/AxiomUnitTestProject/AxiomUnitTestProjectr/TestData.cs new file mode 100644 index 0000000..ded07d8 --- /dev/null +++ b/AxiomUnitTestProject/AxiomUnitTestProjectr/TestData.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AxiomUnitTestProject +{ + public class TestData + { + public static List CodeLines() + { + List codeLines = new List(); + codeLines.Add("DECLARE A,B;A=1;B=5;WHILE(A=5){user_a=1;user_b=1;user_c=1;}"); + codeLines.Add("DECLARE price,operation;operation='OPEN';price=GETPRICE('MIDD','07-12-2021',operation);"); + codeLines.Add("DECLARE var1,var2,var3,var4;var1='Hello';var2=' ';var3='World';var4=UPPER(var1)+UPPER(var2)+UPPER(var3)"); + codeLines.Add("DECLARE var1,var2,var3,var4;var1='2';var2='4';var3='6';var4=CONVERT(var1,'System.Double')+CONVERT(var2,'System.Double')+CONVERT(var3,'System.Double');"); + codeLines.Add("DECLARE var1,var2,var3,var4;var1='2';var2='4';var3='6';var4=CONVERT(var1,'System.Double')*CONVERT(var2,'System.Double')*CONVERT(var3,'System.Double');"); + codeLines.Add("DECLARE var1,var2,var3,var4;var1=-1;var2=-2;var3=-3;var4=abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2)*abs(var2);"); + codeLines.Add("DECLARE var1,var2,var3,var4;var1=1;var2=2;var3=3;var4=var1*var2*var3*var1*var2*var3*abs(var1);"); + codeLines.Add("DECLARE var1,var2,var3,var4;var1=1;var2=2;var3=3;var4=var1*var2*var3*var1*var2*var3;"); + codeLines.Add("DECLARE FIN.Securities.IndustryClass4,FIN.Securities.Country,FIN.Securities.ISIN;FIN.Securities.ISIN='ARARGE';IF(FIN.Securities.ISIN LIKE 'ARARGE'){FIN.Securities.IndustryClass4 = 'Treasury Bond';FIN.Securities.Country='USD'};"); + codeLines.Add("#directive_clear_modified;"); + codeLines.Add("DECLARE ENTITY_ID,EFFECTIVE_DATE;ENTITY_ID=null;IF(ENTITY_ID==null)THEN EFFECTIVE_DATE=CONVERT('1/1/1','System.DateTime');"); + codeLines.Add("DECLARE ENTITY_ID;ENTITY_ID='';IF(ENTITY_ID=='')THEN ENTITY_ID='ENTITY_ID IS BLANK'ELSE ENTITY_ID='ENTITY_ID IS NOT BLANK';"); + codeLines.Add("DECLARE ENTITY_ID,AXIOM_META_TAG;ENTITY_ID=148;IF(ENTITY_ID==148)THEN AXIOM_META_TAG=ENTITY_ID+'_BG' ELSE AXIOM_META_TAG=null;"); + codeLines.Add("DECLARE OAC;OAC=-3.52E-05;"); + codeLines.Add("DECLARE FIN.Analytics.OAD,LAND.STG_EC.SecurityIdentifier;FIN.Analytics.OAD=0.50;LAND.STG_EC.SecurityIdentifier = '397863';IF(LAND.STG_EC.SecurityIdentifier == '397863') THEN FIN.Analytics.OAD = FIN.Analytics.OAD*2.00;"); + codeLines.Add("DECLARE A,B;A=99;if(A<>99)then B=1 else B=2;"); + codeLines.Add("DECLARE A,B,C;A='45';B='2';C=A+B;"); // Ok, concatenation of two strings + codeLines.Add("DECLARE A,B,C;A='45';B='2';C=A*B;"); // Converts the strings to double and then performs the multiplication + codeLines.Add("DECLARE A,B,C,D;A='45';B='2';D='2';C=CONVERT(A,'System.Double')*CONVERT(B,'System.Double')*CONVERT(D,'System.Double');"); // Ok, multiplying numerical values + codeLines.Add("DECLARE A,B,C,D;A='45';B='2';D='2';C=CONVERT(A,'System.Double')*CONVERT(B,'System.Double')*2;"); // Ok, multiplying numerical values + codeLines.Add("DECLARE A,B,C,D;A='45';B='2';D='2';C=CONVERT(A,'System.Double')+CONVERT(B,'System.Double');"); // Ok, multiplying numerical values + codeLines.Add("DECLARE A,B,C,D;A='45';B='2';D='2';C=CONVERT(A,'System.Double')+CONVERT(B,'System.Double')+CONVERT(D,'System.Double');"); // Ok, multiplying numerical values + codeLines.Add("DECLARE RESULT,A,B,C,D;A=CONVERT('01-01-2018','System.DateTime');B=CONVERT('01-02-2018','System.DateTime');IF(A>B) THEN RESULT='01-01-2018 IS GREATER THAN 01-02-2018' ELSE RESULT='01-02-2018 IS GREATER THAN 01-01-2018';"); + codeLines.Add("DECLARE RESULT,A,B,C,D;A=null;B=null;C='NotNull';RESULT=ISNULL(A,B,C);"); + codeLines.Add("DECLARE a,b,c;a=100;b=100+a;c=-100;"); + codeLines.Add("DECLARE NOTIONAL,DELTA,DELTA_ADJUSTED_NOTIONAL;NOTIONAL=1000.00;DELTA=.2017;DELTA_ADJUSTED_NOTIONAL=NOTIONAL/DELTA;"); + codeLines.Add("DECLARE NOTIONAL,DELTA,DELTA_ADJUSTED_NOTIONAL;NOTIONAL=20;DELTA=100;DELTA_ADJUSTED_NOTIONAL=NOTIONAL/DELTA;"); + codeLines.Add("DECLARE NOTIONAL,DELTA,DELTA_ADJUSTED_NOTIONAL;NOTIONAL=20.00;if(NOTIONAL==20)then DELTA=.01 else DELTA=1.00;"); + codeLines.Add("DECLARE NOTIONAL,DELTA,DELTA_ADJUSTED_NOTIONAL;NOTIONAL=10.00;if(NOTIONAL<>20) then DELTA=.01 else DELTA=1.00;"); + codeLines.Add("DECLARE NOTIONAL,DELTA,DELTA_ADJUSTED_NOTIONAL;NOTIONAL=20.00;if(2==2)then DELTA=.01 else DELTA=1.00;"); + codeLines.Add("DECLARE NOTIONAL,DELTA,DELTA_ADJUSTED_NOTIONAL;NOTIONAL=20.00;if(3==2)then DELTA=.01 else DELTA=1.00;"); + codeLines.Add("DECLARE NUM1;NUM1=3*4*(2+1)"); + codeLines.Add("DECLARE A,B,C;A=2;B=.5;C=pow(A,B);"); + codeLines.Add("DECLARE A,B,C;A=100;IF(A<200) THEN B=1 ELSE B=0;"); + codeLines.Add("DECLARE A,B,C;A=CONVERT('03-10-2018','System.DateTime');"); + codeLines.Add("DECLARE A,B,C;A=CONVERT('2','System.Int32');B=CONVERT('3','System.Int32');"); + codeLines.Add("DECLARE A,B,C;A=100/50;B=100-(((2*2)*8)*9);"); + codeLines.Add("DECLARE A,B,C;A=abs(-50);"); + codeLines.Add("DECLARE A,B,C;A=abs(-50);"); + codeLines.Add("DECLARE A,B,C;A=99;"); + codeLines.Add("DECLARE A,B,C;A=CONVERT('2','System.Int32');B=CONVERT('2','System.Int32');IF(A==B)THEN C=1 ELSE C=2;"); + codeLines.Add("DECLARE CURRENCY,A;CURRENCY='MXN';A=CURRENCY in('USD','JPY');"); + codeLines.Add("DECLARE CURRENCY,RESULT;CURRENCY='MXN';if(CURRENCY in('USD','JPY','MXN'))THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE CURRENCY,RESULT;CURRENCY='MXN';if(CURRENCY LIKE '%MXN%') THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE CURRENCY,START_INDEX,LENGTH,CURRENCY_CODE;CURRENCY='MXN12345';START_INDEX=1;LENGTH=3;CURRENCY_CODE=SUBSTRING(CURRENCY,START_INDEX,LENGTH);"); + codeLines.Add("DECLARE IS_PRIMARY_LEG,SEC_ID,LEG;IS_PRIMARY_LEG='FALSE';SEC_ID='FXF12345678_1';LEG=SUBSTRING(SEC_ID,13,1);IF(LEG==1) THEN IS_PRIMARY_LEG='TRUE' ELSE IS_PRIMARY_LEG='FALSE';"); + codeLines.Add("DECLARE A,B;A=100/50;B=100-(((2*2)*8)*9);"); + codeLines.Add("DECLARE IS_PRIMARY_LEG,SEC_ID;IS_PRIMARY_LEG='FALSE';SEC_ID='FXF12345678_1';IF(SUBSTRING(SEC_ID,13,1)==1)THEN IS_PRIMARY_LEG='TRUE' ELSE IS_PRIMARY_LEG='FALSE';"); + codeLines.Add("DECLARE SEC_ID,B;SEC_ID='FXF12345678_1';B=SUBSTRING(SEC_ID,13,1);"); + codeLines.Add("DECLARE IS_PRIMARY_LEG,SEC_ID;IS_PRIMARY_LEG='FALSE';SEC_ID='FXF12345678_1';IF(SEC_ID LIKE '%_1')THEN IS_PRIMARY_LEG='TRUE' ELSE IS_PRIMARY_LEG='FALSE';"); + codeLines.Add("DECLARE IS_FX,SEC_ID;IS_FX='FALSE';SEC_ID='FXF12345678_1';IF(SEC_ID LIKE 'FXF2%' OR SEC_ID LIKE 'FXF1%')THEN IS_FX='TRUE' ELSE IS_FX='FALSE';"); + codeLines.Add("DECLARE A;A=2;"); + codeLines.Add("DECLARE A,B,C,D;A=2;B=0;C=9;IF(A==2 AND B==0 AND C==10) THEN D=1 ELSE D=0;"); + codeLines.Add("DECLARE LOCAL_AMT,SECURITY_ID,ENTRYCOST;LOCAL_AMT=50.00;SECURITY_ID='BP071917P1HY5';IF(SECURITY_ID in('BP071917P1HY5','BP071917P2HY5','BP071917P3HY5','BP071917P4HY5','BP071917P5HY5','BP071917P6HY5')) THEN ENTRYCOST=100.00 ELSE ENTRYCOST=LOCAL_AMT;"); + codeLines.Add("DECLARE A;A=null;"); + codeLines.Add("DECLARE A,B;A=1;B=2;IF(A==1){IF(B==2)THEN A=10 ELSE A=5;}else{A=3;B=4;}"); + codeLines.Add("DECLARE A,B,C;A=null;B='TRUE';C=ISNULL(A,B);"); + codeLines.Add("DECLARE A,B;A=1;B=2;IF(A==2)THEN B=100 ELSE B=200;"); + codeLines.Add("DECLARE AssetLevel1,IndustryClass4,RESULT;AssetLevel1='FUTURE';IndustryClass4='BOND_FUTURES';IF(AssetLevel1 like 'FUTURE' AND IndustryClass4=='BOND_FUTURES')THEN RESULT=1 ELSE RESULT=0;"); + codeLines.Add("DECLARE A,B,RESULT;A=1;B=2;IF(A==1 AND B==2)THEN RESULT=1 ELSE RESULT=0;"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=1;IF((VAR1=='YES') AND VAR2=='NO' AND VAR4==1) THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF(VAR1=='NO' OR (VAR2=='YES' AND VAR4==1)) THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF(VAR1=='YES' OR VAR2=='YES' AND VAR4==2) THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF((VAR1=='YES') OR (VAR2=='YES') AND (VAR4==1)) THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF(VAR1=='YES' AND (VAR2=='YES') AND VAR4==1) THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='YES';VAR4=1;IF((VAR1=='YES') AND VAR2=='NO') THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=1;IF((VAR1=='YES') AND VAR2=='NO') THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=1;IF((((((VAR1=='YES')))))) THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1='YES';VAR2='NO';VAR4=1;IF(VAR1=='YES') THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1=2;IF(VAR1==2) THEN RESULT='TRUE' ELSE RESULT='FALSE';"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1=((ABS(-1)+2)+3);"); + codeLines.Add("DECLARE VAR1,VAR2,VAR4,RESULT;VAR1=-1;VAR2=-3;VAR2=ABS(VAR2)+1;"); + codeLines.Add("DECLARE A,B,C;A=1;B=2;C=3;IF(B>A){A=0;B=0;C=0;}ELSE{A=1;B=1;C=1;}"); + codeLines.Add("DECLARE A,B,C;A=1;B=2;C=3;IF(B + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Configs/STAGE/Janus.AxiomConsole.exe.config b/Configs/STAGE/Janus.AxiomConsole.exe.config new file mode 100644 index 0000000..43d44f7 --- /dev/null +++ b/Configs/STAGE/Janus.AxiomConsole.exe.config @@ -0,0 +1,70 @@ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Notes.txt b/Notes.txt new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..4173dd3 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# Axiom + +## A rules engine for processing overrides. + diff --git a/References/MarketDataLib.dll b/References/MarketDataLib.dll new file mode 100644 index 0000000..0b04341 Binary files /dev/null and b/References/MarketDataLib.dll differ diff --git a/References/MySql.Data.dll b/References/MySql.Data.dll new file mode 100644 index 0000000..2fd44b9 Binary files /dev/null and b/References/MySql.Data.dll differ