First Commit
This commit is contained in:
commit
c3afc99003
|
@ -0,0 +1,398 @@
|
||||||
|
## 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/main/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# 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
|
||||||
|
nunit-*.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/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.tlog
|
||||||
|
*.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
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# 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
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# 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
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# 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 6 auto-generated project file (contains which files were open etc.)
|
||||||
|
*.vbp
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||||
|
*.dsw
|
||||||
|
*.dsp
|
||||||
|
|
||||||
|
# Visual Studio 6 technical files
|
||||||
|
*.ncb
|
||||||
|
*.aps
|
||||||
|
|
||||||
|
# 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/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# 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/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# Visual Studio History (VSHistory) files
|
||||||
|
.vshistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
# VS Code files for those working on multiple tools
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Windows Installer files from build outputs
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
*.sln.iml
|
|
@ -0,0 +1,415 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace TLang.Lexer
|
||||||
|
{
|
||||||
|
public class Lex
|
||||||
|
{
|
||||||
|
TextReader reader;
|
||||||
|
private Lex(TextReader reader)
|
||||||
|
{
|
||||||
|
this.reader = reader;
|
||||||
|
}
|
||||||
|
private LexLineInfo lineInfo = new LexLineInfo();
|
||||||
|
private LexLineInfo beginLInfo = new LexLineInfo();
|
||||||
|
private List<LexToken> tokens = new List<LexToken>();
|
||||||
|
private StringBuilder builder = new StringBuilder();
|
||||||
|
private void Flush()
|
||||||
|
{
|
||||||
|
if(builder.Length > 0)
|
||||||
|
{
|
||||||
|
tokens.Add(LexToken.Token(builder.ToString()).WithLineInfo(beginLInfo));
|
||||||
|
builder.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void Append(int c)
|
||||||
|
{
|
||||||
|
if(c == -1) return;
|
||||||
|
if(builder.Length == 0)
|
||||||
|
beginLInfo = lineInfo.Clone();
|
||||||
|
|
||||||
|
builder.Append((char)c);
|
||||||
|
|
||||||
|
}
|
||||||
|
public static LexContext GetTokens(TextReader reader,string filename="memory.tlang")
|
||||||
|
{
|
||||||
|
Lex lex = new Lex(reader);
|
||||||
|
lex.StartLexing();
|
||||||
|
return new LexContext(lex.tokens);
|
||||||
|
}
|
||||||
|
private void ParseChar()
|
||||||
|
{
|
||||||
|
var lineInfo = this.lineInfo.Clone();
|
||||||
|
//'c'
|
||||||
|
var (mChar,Escaped,EOF) = ReadChar();
|
||||||
|
|
||||||
|
tokens.Add(LexToken.Char(mChar.ToString()).WithLineInfo(lineInfo));
|
||||||
|
_ = Next;
|
||||||
|
}
|
||||||
|
private void ParseString(bool interoplated)
|
||||||
|
{
|
||||||
|
var lineInfo = this.lineInfo.Clone();
|
||||||
|
//$"Demi Lovato is { variable + 5 } years Old"; -> String.Join("Demi Lovato is ",( variable + 5)," years Old");
|
||||||
|
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
var (mChar,Escaped,EOF) = ReadChar();
|
||||||
|
|
||||||
|
while((mChar != '\"' || Escaped) && !EOF)
|
||||||
|
{
|
||||||
|
b.Append(mChar);
|
||||||
|
(mChar,Escaped,EOF) = ReadChar();
|
||||||
|
}
|
||||||
|
if(interoplated)
|
||||||
|
{
|
||||||
|
|
||||||
|
tokens.Add(LexToken.Token("String").WithLineInfo(lineInfo));
|
||||||
|
tokens.Add(LexToken.Token(".").WithLineInfo(lineInfo));
|
||||||
|
tokens.Add(LexToken.Token("Concat").WithLineInfo(lineInfo));
|
||||||
|
tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo));
|
||||||
|
int e = 0;
|
||||||
|
int escapeI = 0;
|
||||||
|
|
||||||
|
StringBuilder b2 = new StringBuilder();
|
||||||
|
for(int i = 0;i< b.Length;i++)
|
||||||
|
{
|
||||||
|
if(b[i] == '{' )
|
||||||
|
{
|
||||||
|
if((i+1 < b.Length && b[i+1] != '{') || escapeI >= 1)
|
||||||
|
{
|
||||||
|
if(b2.Length > 0 && escapeI < 1)
|
||||||
|
{
|
||||||
|
if(e > 0) tokens.Add(LexToken.Token(",").WithLineInfo(lineInfo));
|
||||||
|
tokens.Add(LexToken.String(b2.ToString()).WithLineInfo(lineInfo));
|
||||||
|
b2.Clear();
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
escapeI++;
|
||||||
|
if(escapeI > 1)
|
||||||
|
{
|
||||||
|
b2.Append('{');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b2.Append('{');
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(b[i] == '}')
|
||||||
|
{
|
||||||
|
if(escapeI >= 1)
|
||||||
|
{
|
||||||
|
escapeI--;
|
||||||
|
if(b2.Length > 0 && escapeI == 0)
|
||||||
|
{
|
||||||
|
if(e > 0) tokens.Add(LexToken.Token(",").WithLineInfo(lineInfo));
|
||||||
|
|
||||||
|
|
||||||
|
tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo));
|
||||||
|
tokens.AddRange(Lex.GetTokensFromString(b2.ToString(),"compilerGenerated.tlang").Tokens);
|
||||||
|
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
|
||||||
|
b2.Clear();
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
if(escapeI >= 1)
|
||||||
|
{
|
||||||
|
b2.Append("}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
b2.Append(b[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(b2.Length > 0)
|
||||||
|
{
|
||||||
|
if(escapeI > 0)
|
||||||
|
{
|
||||||
|
if(e > 0) tokens.Add(LexToken.Token(",").WithLineInfo(lineInfo));
|
||||||
|
|
||||||
|
|
||||||
|
tokens.Add(LexToken.Token("(").WithLineInfo(lineInfo));
|
||||||
|
tokens.AddRange(Lex.GetTokensFromString(b2.ToString(),"compilerGenerated.tlang").Tokens);
|
||||||
|
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
|
||||||
|
b2.Clear();
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(e > 0) tokens.Add(LexToken.Token(",").WithLineInfo(lineInfo));
|
||||||
|
tokens.Add(LexToken.String(b2.ToString()).WithLineInfo(lineInfo));
|
||||||
|
b2.Clear();
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tokens.Add(LexToken.Token(")").WithLineInfo(lineInfo));
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tokens.Add(LexToken.String(b.ToString()).WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private (char Char, bool Escaped,bool EOF) ReadChar()
|
||||||
|
{
|
||||||
|
|
||||||
|
int next = Next;
|
||||||
|
if(next == -1) return (' ',false,true);
|
||||||
|
if(next == '\\')
|
||||||
|
{
|
||||||
|
next = Next;
|
||||||
|
if(next == 'n')
|
||||||
|
{
|
||||||
|
return ('\n',true,false);
|
||||||
|
}
|
||||||
|
else if(next == 'r')
|
||||||
|
{
|
||||||
|
return ('\r',true,false);
|
||||||
|
}
|
||||||
|
else if(next == 't')
|
||||||
|
{
|
||||||
|
return ('\t',true,false);
|
||||||
|
}
|
||||||
|
else if(next == 'x')
|
||||||
|
{
|
||||||
|
string hexCode = new string(new char[]{(char)Next,(char)Next});
|
||||||
|
int val= int.Parse(hexCode,System.Globalization.NumberStyles.HexNumber);
|
||||||
|
return ((char)val,true,false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((char)next,true,false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ((char)next,false,false);
|
||||||
|
}
|
||||||
|
private void StartLexing()
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
while((c=Next) != -1)
|
||||||
|
{
|
||||||
|
var peek = Peek;
|
||||||
|
var lineInfo = this.lineInfo.Clone();
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case '/':
|
||||||
|
if(peek == '/')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
//single line comment
|
||||||
|
Flush();
|
||||||
|
while(Next != '\n');
|
||||||
|
}
|
||||||
|
else if(peek == '*')
|
||||||
|
{
|
||||||
|
var next = Next;
|
||||||
|
|
||||||
|
while((next = Next) != -1)
|
||||||
|
{
|
||||||
|
if(next == '*')
|
||||||
|
{
|
||||||
|
if(Peek == '/')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(peek == '^')
|
||||||
|
{
|
||||||
|
var next = Next;
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
|
||||||
|
while((next = Next) != -1)
|
||||||
|
{
|
||||||
|
if(next == '^')
|
||||||
|
{
|
||||||
|
if(Peek == '/')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.Append((char)next);
|
||||||
|
}
|
||||||
|
tokens.Add(LexToken.Documentation(b.ToString()).WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
else if(peek == '=')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}=").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
Flush();
|
||||||
|
ParseString(false);
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
Flush();
|
||||||
|
ParseChar();
|
||||||
|
break;
|
||||||
|
case '$':
|
||||||
|
Flush();
|
||||||
|
if(peek == '\"')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
ParseString(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '^':
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
if(peek == c)
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
peek=Peek;
|
||||||
|
if(peek == '=')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}{(char)c}=").WithLineInfo(lineInfo));
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(peek == '=')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}=").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
case '|':
|
||||||
|
case '&':
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
if(peek == c)
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
else if(peek == '=')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}=").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
case '%':
|
||||||
|
case '!':
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
if(peek == '=')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}=").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case ':':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case ';':
|
||||||
|
case '?':
|
||||||
|
case '.':
|
||||||
|
case ',':
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '=':
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
if(peek == c)
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
else if(peek == '>')
|
||||||
|
{
|
||||||
|
_ = Next;
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}>").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tokens.Add(LexToken.Token($"{(char)c}").WithLineInfo(lineInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case ' ':
|
||||||
|
Flush();
|
||||||
|
SetSpacesBetweenTrue();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Append(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetSpacesBetweenTrue()
|
||||||
|
{
|
||||||
|
if(tokens.Count > 0)
|
||||||
|
{
|
||||||
|
tokens[tokens.Count-1].SpacesBetweenThisAndNext = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int Next {
|
||||||
|
get{
|
||||||
|
int read= reader.Read();
|
||||||
|
if(read != -1)
|
||||||
|
lineInfo.AppendChar((char)read);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int Peek => reader.Peek();
|
||||||
|
|
||||||
|
public static LexContext GetTokensFromFile(string str)
|
||||||
|
{
|
||||||
|
using(var f = File.OpenText(str))
|
||||||
|
{
|
||||||
|
return GetTokens(f,str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static LexContext GetTokensFromString(string str,string filename="memory.tlang")
|
||||||
|
{
|
||||||
|
return GetTokens(new StringReader(str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace TLang.Lexer
|
||||||
|
{
|
||||||
|
public class LexContext
|
||||||
|
{
|
||||||
|
public static LexContext operator+(LexContext left,LexContext right)
|
||||||
|
{
|
||||||
|
List<LexToken> tokens=new List<LexToken>();
|
||||||
|
tokens.AddRange(left.Tokens);
|
||||||
|
tokens.AddRange(right.Tokens);
|
||||||
|
|
||||||
|
LexContext ctx=new LexContext(tokens);
|
||||||
|
ctx.Offset = left.Offset;
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
public LexContext(IReadOnlyList<LexToken> tokens)
|
||||||
|
{
|
||||||
|
Tokens = tokens;
|
||||||
|
}
|
||||||
|
public IReadOnlyList<LexToken> Tokens {get;}
|
||||||
|
public int Offset {get;set;} = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public LexContext FromOffset(int offset)
|
||||||
|
{
|
||||||
|
return new LexContext(Tokens){Offset = offset};
|
||||||
|
}
|
||||||
|
public LexContext FromOffset()
|
||||||
|
{
|
||||||
|
return FromOffset(Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LexToken Next(int i = 0)
|
||||||
|
{
|
||||||
|
if(Offset + i < Tokens.Count) return Tokens[Offset + i];
|
||||||
|
return new LexToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(int i=1)
|
||||||
|
{
|
||||||
|
Offset++;
|
||||||
|
}
|
||||||
|
public LexEntryContext NextEntriesNoSpaces(bool consumeIfTrue,params string[] tokenText)
|
||||||
|
{
|
||||||
|
List<LexToken> tokens = new List<LexToken>();
|
||||||
|
int offset = Offset;
|
||||||
|
if(Offset + tokenText.Length >= Tokens.Count) return new LexEntryContext(tokens,offset,false);
|
||||||
|
for(int i = 0; i<tokenText.Length; i++)
|
||||||
|
{
|
||||||
|
if(Tokens[i+offset].IsDocumentation || Tokens[i+offset].SpacesBetweenThisAndNext || Tokens[i+offset].IsChar || Tokens[i+offset].IsString || Tokens[i+offset].Text != tokenText[i]) return new LexEntryContext(tokens,offset,false);
|
||||||
|
|
||||||
|
tokens.Add(Tokens[i+offset]);
|
||||||
|
}
|
||||||
|
if(consumeIfTrue) Offset += tokenText.Length;
|
||||||
|
return new LexEntryContext(tokens,offset,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LexEntryContext NextEntries(bool consumeIfTrue,params string[] tokenText)
|
||||||
|
{
|
||||||
|
List<LexToken> tokens = new List<LexToken>();
|
||||||
|
int offset = Offset;
|
||||||
|
if(Offset + tokenText.Length >= Tokens.Count) return new LexEntryContext(tokens,offset,false);
|
||||||
|
for(int i = 0; i<tokenText.Length; i++)
|
||||||
|
{
|
||||||
|
if(Tokens[i+offset].IsDocumentation || Tokens[i+offset].IsChar || Tokens[i+offset].IsString || Tokens[i+offset].Text != tokenText[i]) return new LexEntryContext(tokens,offset,false);
|
||||||
|
|
||||||
|
tokens.Add(Tokens[i+offset]);
|
||||||
|
}
|
||||||
|
if(consumeIfTrue) Offset += tokenText.Length;
|
||||||
|
return new LexEntryContext(tokens,offset,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool NextEntryIsAnyOf(bool consumeIfTrue,out LexToken token, params string[] tokenText)
|
||||||
|
{
|
||||||
|
token = new LexToken();
|
||||||
|
if(Offset >= Tokens.Count) return false;
|
||||||
|
|
||||||
|
foreach(var item in tokenText)
|
||||||
|
{
|
||||||
|
if(Tokens[Offset].IsDocumentation || Tokens[Offset].IsChar || Tokens[Offset].IsString || Tokens[Offset].Text == item)
|
||||||
|
{
|
||||||
|
token = Tokens[Offset];
|
||||||
|
if(consumeIfTrue) Offset++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LexToken NextEntry
|
||||||
|
{
|
||||||
|
get {
|
||||||
|
if(Offset < Tokens.Count)
|
||||||
|
{
|
||||||
|
return Tokens[Offset++];
|
||||||
|
}
|
||||||
|
return LexToken.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public LexToken PeekEntry
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(Offset < Tokens.Count)
|
||||||
|
{
|
||||||
|
return Tokens[Offset];
|
||||||
|
}
|
||||||
|
return LexToken.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LexLineInfo CurrentLineInfo => PeekEntry.Position;
|
||||||
|
|
||||||
|
public bool MoreTokens => Offset < Tokens.Count;
|
||||||
|
|
||||||
|
public string PopDocumentation()
|
||||||
|
{
|
||||||
|
if(Offset >= Tokens.Count || !Tokens[Offset].IsDocumentation) return "";
|
||||||
|
return Tokens[Offset++].Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LexEntryContext NextEntries(bool consumeIfTrue,params LexToken[] tokens)
|
||||||
|
{
|
||||||
|
List<LexToken> _tokens = new List<LexToken>();
|
||||||
|
int offset = Offset;
|
||||||
|
if(Offset + tokens.Length >= Tokens.Count) return new LexEntryContext(_tokens,offset,false);
|
||||||
|
for(int i = 0; i<tokens.Length; i++)
|
||||||
|
{
|
||||||
|
if(Tokens[i+offset].SameToken(tokens[i])) return new LexEntryContext(_tokens,offset,false);
|
||||||
|
_tokens.Add(Tokens[i+offset]);
|
||||||
|
}
|
||||||
|
if(consumeIfTrue) Offset += tokens.Length;
|
||||||
|
return new LexEntryContext(_tokens,offset,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace TLang.Lexer
|
||||||
|
{
|
||||||
|
public class LexEntryContext
|
||||||
|
{
|
||||||
|
public LexEntryContext(List<LexToken> tokens,int offset,bool success)
|
||||||
|
{
|
||||||
|
Tokens = tokens;
|
||||||
|
Offset = offset;
|
||||||
|
Success = success;
|
||||||
|
}
|
||||||
|
public IReadOnlyList<LexToken> Tokens {get;}
|
||||||
|
|
||||||
|
public int Offset {get;}
|
||||||
|
|
||||||
|
public bool Success {get;}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
using System;
|
||||||
|
namespace TLang.Lexer
|
||||||
|
{
|
||||||
|
public class LexLineInfo : IEquatable<LexLineInfo>
|
||||||
|
{
|
||||||
|
|
||||||
|
public LexLineInfo()
|
||||||
|
{
|
||||||
|
Line = 1;
|
||||||
|
Position = 0;
|
||||||
|
Column = 1;
|
||||||
|
FileName="memory.tlang";
|
||||||
|
}
|
||||||
|
public string FileName {get;set;}
|
||||||
|
|
||||||
|
public int Line {get;set;}
|
||||||
|
|
||||||
|
public int Column {get;set;}
|
||||||
|
|
||||||
|
public int Position {get;set;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void AppendChar(char c)
|
||||||
|
{
|
||||||
|
Position++;
|
||||||
|
if(c == '\t')
|
||||||
|
{
|
||||||
|
Column += 4;
|
||||||
|
}
|
||||||
|
else if(c == '\r')
|
||||||
|
{
|
||||||
|
Column = 1;
|
||||||
|
}
|
||||||
|
else if(c == '\n')
|
||||||
|
{
|
||||||
|
Column = 1;
|
||||||
|
Line += 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Column++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LexLineInfo Clone()
|
||||||
|
{
|
||||||
|
LexLineInfo lineInfo=new LexLineInfo();
|
||||||
|
lineInfo.Column = Column;
|
||||||
|
lineInfo.FileName = FileName;
|
||||||
|
lineInfo.Line = Line;
|
||||||
|
lineInfo.Position = Position;
|
||||||
|
return lineInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(LexLineInfo other)
|
||||||
|
{
|
||||||
|
return Line == other.Line && Column == other.Column && FileName == other.FileName && Position == other.Position;
|
||||||
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"in file: {FileName}:{Line} offset: {Position}, col: {Column}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
using System;
|
||||||
|
namespace TLang.Lexer
|
||||||
|
{
|
||||||
|
public class LexToken : IEquatable<LexToken>
|
||||||
|
{
|
||||||
|
public static LexToken Empty => new LexToken();
|
||||||
|
public bool IsEmpty => Text.Length == 0 && !IsDocumentation && !IsChar && !IsString;
|
||||||
|
public static LexToken Documentation(string text)
|
||||||
|
{
|
||||||
|
LexToken token = new LexToken();
|
||||||
|
token.IsDocumentation =true;
|
||||||
|
token.IsChar = false;
|
||||||
|
token.IsString = false;
|
||||||
|
token.Text = text;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
public static LexToken Token(string text)
|
||||||
|
{
|
||||||
|
LexToken token = new LexToken();
|
||||||
|
token.IsDocumentation=false;
|
||||||
|
token.IsChar = false;
|
||||||
|
token.IsString = false;
|
||||||
|
token.Text = text;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
public static LexToken String(string text)
|
||||||
|
{
|
||||||
|
LexToken token = new LexToken();
|
||||||
|
token.IsDocumentation=false;
|
||||||
|
token.IsChar = false;
|
||||||
|
token.IsString = true;
|
||||||
|
token.Text = text;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
public static LexToken Char(string text)
|
||||||
|
{
|
||||||
|
LexToken token = new LexToken();
|
||||||
|
token.IsDocumentation=false;
|
||||||
|
token.IsChar = true;
|
||||||
|
token.IsString = false;
|
||||||
|
token.Text = text;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
public bool SpacesBetweenThisAndNext {get;set;} = false;
|
||||||
|
public LexToken WithLineInfo(LexLineInfo lineInfo)
|
||||||
|
{
|
||||||
|
Position = lineInfo.Clone();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public LexToken WithLineInfo(int line,int col,int offset,string filename="memory.tlang")
|
||||||
|
{
|
||||||
|
Position = new LexLineInfo(){Line = line,Column = col,Position = offset,FileName = filename};
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public LexLineInfo Position {get;set;} = new LexLineInfo();
|
||||||
|
public string Text {get;set;}="";
|
||||||
|
|
||||||
|
public bool IsString {get;set;}=false;
|
||||||
|
|
||||||
|
public bool IsChar {get;set;}=false;
|
||||||
|
|
||||||
|
public bool IsDocumentation {get;set;}=false;
|
||||||
|
|
||||||
|
public bool SameToken(LexToken token)
|
||||||
|
{
|
||||||
|
return Text == token.Text && IsChar == token.IsChar && IsString == token.IsString && IsDocumentation == token.IsDocumentation;
|
||||||
|
}
|
||||||
|
public bool Equals(LexToken token)
|
||||||
|
{
|
||||||
|
return Text == token.Text && IsChar == token.IsChar && IsString == token.IsString && IsDocumentation == token.IsDocumentation && SpacesBetweenThisAndNext == token.SpacesBetweenThisAndNext && Position.Equals(token.Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsTokenWith(string text)
|
||||||
|
{
|
||||||
|
return !IsChar && !IsDocumentation && !IsString && Text == text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class AddNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public AddNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class BAndNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public BAndNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class BOrNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public BOrNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class BitwiseNotNode : Node
|
||||||
|
{
|
||||||
|
public Node Node {get;set;}
|
||||||
|
|
||||||
|
public BitwiseNotNode(Node node)
|
||||||
|
{
|
||||||
|
Node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class BreakNode : Node
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class CallNode : SymbolNode
|
||||||
|
{
|
||||||
|
public List<Node> Arguments {get;set;}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class CaseNode : Node
|
||||||
|
{
|
||||||
|
public Node Variable {get;set;}
|
||||||
|
public Node Body {get;set;}
|
||||||
|
|
||||||
|
public CaseNode(Node expr, Node node)
|
||||||
|
{
|
||||||
|
Variable = expr;
|
||||||
|
Body = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class CharNode : Node
|
||||||
|
{
|
||||||
|
public string Text {get;set;}
|
||||||
|
|
||||||
|
public CharNode(string text)
|
||||||
|
{
|
||||||
|
Text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,653 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using TLang.Lexer;
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class Parse
|
||||||
|
{
|
||||||
|
private Parse(LexContext ctx)
|
||||||
|
{
|
||||||
|
Context = ctx;
|
||||||
|
}
|
||||||
|
private LexContext Context {get;set;}
|
||||||
|
private Node Node {get;set;}
|
||||||
|
private void ParseNodeRoot()
|
||||||
|
{
|
||||||
|
Node = ParseNode(true);
|
||||||
|
}
|
||||||
|
public static Node ParseFromLexContext(params LexContext[] ctx)
|
||||||
|
{
|
||||||
|
if(ctx.Length > 0)
|
||||||
|
{
|
||||||
|
var ctx2 = ctx[0];
|
||||||
|
for(int i = 1;i<ctx.Length;i++)
|
||||||
|
{
|
||||||
|
ctx2 += ctx[i];
|
||||||
|
}
|
||||||
|
Parse p=new Parse(ctx2);
|
||||||
|
p.ParseNodeRoot();
|
||||||
|
return p.Node;
|
||||||
|
}
|
||||||
|
return new Node();
|
||||||
|
}
|
||||||
|
public static Node ParseFromTextReader(TextReader reader,string filename="memory.tlang")
|
||||||
|
{
|
||||||
|
var lexed = Lex.GetTokens(reader,filename);
|
||||||
|
return ParseFromLexContext(lexed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node ParseFromFiles(params string[] filenames)
|
||||||
|
{
|
||||||
|
return ParseFromLexContext(filenames.Select<string,LexContext>(e=>Lex.GetTokensFromFile(e)).ToArray());
|
||||||
|
}
|
||||||
|
public static Node ParseFromString(string str,string filename="memory.tlang")
|
||||||
|
{
|
||||||
|
var lexed=Lex.GetTokensFromString(str,filename);
|
||||||
|
return ParseFromLexContext(lexed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseNode(bool isRoot=false,bool inCase=false)
|
||||||
|
{
|
||||||
|
|
||||||
|
ScopeNode node = new ScopeNode();
|
||||||
|
node.LineInfo = Context.CurrentLineInfo;
|
||||||
|
|
||||||
|
|
||||||
|
while(Context.Offset < Context.Tokens.Count && (isRoot || !Context.NextEntries(true,"}").Success))
|
||||||
|
{
|
||||||
|
if(Context.NextEntries(true,"{").Success)
|
||||||
|
{
|
||||||
|
node.Add(ParseNode());
|
||||||
|
}
|
||||||
|
node.Add(ParseAssigable());
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseAssigable()
|
||||||
|
{
|
||||||
|
Node expr = ParseLOr();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"=","+=","-=","*=","/=","%=","|=","&=","^=","^^="))
|
||||||
|
{
|
||||||
|
if(token.Text == "=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,ParseLOr()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "+=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new AddNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "-=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new SubtractNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "*=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new MultiplyNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "/=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new DivideNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "%=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new ModuloNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "|=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new BOrNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "&=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new BAndNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "^=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new XOrNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "^^=")
|
||||||
|
{
|
||||||
|
var symbolNode = expr as SymbolNode;
|
||||||
|
if(symbolNode == null) throw new CompilerError("Assigning variable to something that is not a symbol",expr);
|
||||||
|
|
||||||
|
expr = new SetVariableNode(symbolNode.Name,new PowNode(new GetVariableNode(symbolNode.Name),ParseLOr())){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseLOr()
|
||||||
|
{
|
||||||
|
Node expr = ParseLAnd();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"||"))
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
expr = new LOrNode(expr,ParseLAnd()){LineInfo=token.Position};
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseLAnd()
|
||||||
|
{
|
||||||
|
Node expr = ParseBOr();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"&&"))
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
expr = new LAndNode(expr,ParseBOr()){LineInfo=token.Position};
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseBOr()
|
||||||
|
{
|
||||||
|
Node expr = ParseXOr();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"|"))
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
expr = new BOrNode(expr,ParseXOr()){LineInfo=token.Position};
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseXOr()
|
||||||
|
{
|
||||||
|
Node expr = ParseBAnd();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"^"))
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
expr = new XOrNode(expr,ParseBAnd()){LineInfo=token.Position};
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseBAnd()
|
||||||
|
{
|
||||||
|
Node expr = ParseEq();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"&"))
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
expr = new BAndNode(expr,ParseEq()){LineInfo=token.Position};
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseEq()
|
||||||
|
{
|
||||||
|
Node expr = ParseRo();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"==","!="))
|
||||||
|
{
|
||||||
|
|
||||||
|
if(token.Text == "==")
|
||||||
|
{
|
||||||
|
expr = new EqualsNode(expr,ParseRo()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "!=")
|
||||||
|
{
|
||||||
|
expr = new NotEqualsNode(expr,ParseRo()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseRo()
|
||||||
|
{
|
||||||
|
Node expr = ParseRo();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"<","<=",">",">="))
|
||||||
|
{
|
||||||
|
|
||||||
|
if(token.Text == "<")
|
||||||
|
{
|
||||||
|
expr = new LessThanNode(expr,ParseShift()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "<=")
|
||||||
|
{
|
||||||
|
expr = new LessThanEqualsNode(expr,ParseShift()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == ">")
|
||||||
|
{
|
||||||
|
expr = new GreaterThanNode(expr,ParseShift()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == ">=")
|
||||||
|
{
|
||||||
|
expr = new GreaterThanEqualsNode(expr,ParseShift()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
private Node ParseShift()
|
||||||
|
{
|
||||||
|
Node expr = ParseSum();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"<<",">>"))
|
||||||
|
{
|
||||||
|
|
||||||
|
if(token.Text == "<<")
|
||||||
|
{
|
||||||
|
expr = new LeftShiftNode(expr,ParseSum()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == ">>")
|
||||||
|
{
|
||||||
|
expr = new RightShiftNode(expr,ParseSum()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseSum()
|
||||||
|
{
|
||||||
|
Node expr = ParseFactor();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"+","-"))
|
||||||
|
{
|
||||||
|
|
||||||
|
if(token.Text == "+")
|
||||||
|
{
|
||||||
|
expr = new AddNode(expr,ParseFactor()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "-")
|
||||||
|
{
|
||||||
|
expr = new SubtractNode(expr,ParseFactor()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseFactor()
|
||||||
|
{
|
||||||
|
Node expr = ParseExpo();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"*","/","%"))
|
||||||
|
{
|
||||||
|
|
||||||
|
if(token.Text == "*")
|
||||||
|
{
|
||||||
|
expr = new MultiplyNode(expr,ParseExpo()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "/")
|
||||||
|
{
|
||||||
|
expr = new DivideNode(expr,ParseExpo()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "%")
|
||||||
|
{
|
||||||
|
expr = new ModuloNode(expr,ParseExpo()){LineInfo=token.Position};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
private Node ParseExpo()
|
||||||
|
{
|
||||||
|
Node expr = ParseValue();
|
||||||
|
while(Context.NextEntryIsAnyOf(true,out var token,"^^"))
|
||||||
|
{
|
||||||
|
expr = new PowNode(expr,ParseValue());
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node ParseValue()
|
||||||
|
{
|
||||||
|
var doc = Context.PopDocumentation();
|
||||||
|
var token = Context.NextEntry;
|
||||||
|
if(token.IsString) return new StringNode(token.Text){LineInfo = token.Position};
|
||||||
|
if(token.IsChar) return new CharNode(token.Text){LineInfo = token.Position};
|
||||||
|
if(token.Text == "(")
|
||||||
|
{
|
||||||
|
var assignable = ParseAssigable();
|
||||||
|
assignable.LineInfo = token.Position;
|
||||||
|
if(!Context.NextEntries(true,")").Success) throw new CompilerError("symbol must be a ')'",assignable);
|
||||||
|
return assignable;
|
||||||
|
}
|
||||||
|
if(token.Text == "class")
|
||||||
|
{
|
||||||
|
ClassNode classInstance = new ClassNode();
|
||||||
|
classInstance.Name = Context.NextEntry.Text;
|
||||||
|
classInstance.Documentation = doc;
|
||||||
|
|
||||||
|
|
||||||
|
if(Context.NextEntries(true,":").Success)
|
||||||
|
{
|
||||||
|
|
||||||
|
classInstance.InheritsFrom = Context.NextEntry.Text;
|
||||||
|
|
||||||
|
}
|
||||||
|
Context.NextEntries(true,"{");
|
||||||
|
while(Context.MoreTokens && !Context.NextEntries(true,"}").Success)
|
||||||
|
{
|
||||||
|
var doc2 = Context.PopDocumentation();
|
||||||
|
var token2 = Context.NextEntry;
|
||||||
|
var modifier = token2.Text;
|
||||||
|
if(Context.NextEntryIsAnyOf(true,out var token3,"func","abst"))
|
||||||
|
{
|
||||||
|
var name = Context.NextEntry.Text;
|
||||||
|
if(Context.NextEntries(true,"(").Success)
|
||||||
|
{
|
||||||
|
var pos = Context.PeekEntry.Position;
|
||||||
|
List<string> args=new List<string>();
|
||||||
|
while(!Context.NextEntries(true,")").Success)
|
||||||
|
{
|
||||||
|
if(Context.NextEntries(true,",").Success) continue;
|
||||||
|
|
||||||
|
if(Context.Offset < Context.Tokens.Count)
|
||||||
|
{
|
||||||
|
var n0 = ParseNode();
|
||||||
|
var n= n0 as GetVariableNode;
|
||||||
|
if(n != null)
|
||||||
|
{
|
||||||
|
args.Add(n.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new CompilerError("Argument must be a GetVariableNode",n0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClassEntryNode nod=new ClassEntryNode(){LineInfo = token2.Position};
|
||||||
|
nod.Abstract = token3.Text == "abst";
|
||||||
|
nod.Documentation = doc2;
|
||||||
|
nod.Modifier = modifier;
|
||||||
|
nod.Name = name;
|
||||||
|
nod.InitialValue = new ClosureNode(args,ParseNode()){LineInfo = pos};
|
||||||
|
classInstance.Entries.Add(nod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClassEntryNode nod = new ClassEntryNode(){LineInfo = token2.Position};
|
||||||
|
nod.Documentation = doc2;
|
||||||
|
nod.Name = Context.NextEntry.Text;
|
||||||
|
if(!Context.NextEntries(true,"=").Success) throw new CompilerError("Invalid member",classInstance);
|
||||||
|
|
||||||
|
nod.Modifier = modifier;
|
||||||
|
nod.InitialValue = ParseNode();
|
||||||
|
classInstance.Entries.Add(nod);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return classInstance;
|
||||||
|
}
|
||||||
|
if(token.Text == "brk" || token.Text == "break")
|
||||||
|
{
|
||||||
|
return new BreakNode(){LineInfo = token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "cont" || token.Text == "continue")
|
||||||
|
{
|
||||||
|
return new ContinueNode(){LineInfo = token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "ret" || token.Text == "return")
|
||||||
|
{
|
||||||
|
return new ReturnNode(ParseNode()){LineInfo = token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "case")
|
||||||
|
{
|
||||||
|
var expr = ParseNode();
|
||||||
|
if(!Context.NextEntries(true,":").Success) throw new CompilerError("Missing :",expr);
|
||||||
|
return new CaseNode(expr,ParseNode(true,true)){LineInfo = token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "default")
|
||||||
|
{
|
||||||
|
var cur = Context.CurrentLineInfo;
|
||||||
|
var r=Context.NextEntries(true,":");
|
||||||
|
if(!r.Success) throw new CompilerError("Missing :",new Node(){LineInfo = cur});
|
||||||
|
return new DefaultNode(ParseNode(true,true)){LineInfo = token.Position};
|
||||||
|
}
|
||||||
|
if(token.Text == "-")
|
||||||
|
{
|
||||||
|
return new NegativeNode(ParseNode());
|
||||||
|
}
|
||||||
|
if(token.Text == "~")
|
||||||
|
{
|
||||||
|
return new BitwiseNotNode(ParseNode());
|
||||||
|
}
|
||||||
|
if(token.Text == "!")
|
||||||
|
{
|
||||||
|
return new NotNode(ParseNode());
|
||||||
|
}
|
||||||
|
if(long.TryParse(token.Text,out var number))
|
||||||
|
{
|
||||||
|
if(Context.NextEntries(true,".").Success)
|
||||||
|
{
|
||||||
|
var entry=Context.NextEntry;
|
||||||
|
if(!entry.IsChar && !entry.IsDocumentation && !entry.IsEmpty && !entry.IsString && double.TryParse($"{number}.{entry.Text}",out var number2))
|
||||||
|
{
|
||||||
|
return new ConstNumberNode(number2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//just a long
|
||||||
|
return new ConstNumberNode(number);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(Context.NextEntries(true,"(").Success)
|
||||||
|
{
|
||||||
|
if(token.Text == "func")
|
||||||
|
{
|
||||||
|
List<string> args=new List<string>();
|
||||||
|
while(!Context.NextEntries(true,")").Success)
|
||||||
|
{
|
||||||
|
if(Context.NextEntries(true,",").Success) continue;
|
||||||
|
|
||||||
|
if(Context.Offset < Context.Tokens.Count)
|
||||||
|
{
|
||||||
|
var n0 = ParseNode();
|
||||||
|
var n= n0 as GetVariableNode;
|
||||||
|
if(n != null)
|
||||||
|
{
|
||||||
|
args.Add(n.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new CompilerError("Argument must be a GetVariableNode",n0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ClosureNode(args,ParseNode());
|
||||||
|
}
|
||||||
|
else if(token.Text == "for")
|
||||||
|
{
|
||||||
|
Node init=new Node();
|
||||||
|
Node condition = new Node();
|
||||||
|
Node inc = new Node();
|
||||||
|
Node body = new Node();
|
||||||
|
if(Context.MoreTokens && (Context.PeekEntry.Text != ")" || Context.PeekEntry.Text != ";"))
|
||||||
|
{
|
||||||
|
init = ParseNode();
|
||||||
|
}
|
||||||
|
Context.NextEntries(true,";");
|
||||||
|
if(Context.MoreTokens && (Context.PeekEntry.Text != ")" || Context.PeekEntry.Text != ";"))
|
||||||
|
{
|
||||||
|
condition = ParseNode();
|
||||||
|
}
|
||||||
|
Context.NextEntries(true,";");
|
||||||
|
if(Context.MoreTokens && (Context.PeekEntry.Text != ")" || Context.PeekEntry.Text != ";"))
|
||||||
|
{
|
||||||
|
inc = ParseNode();
|
||||||
|
}
|
||||||
|
Context.NextEntries(true,")");
|
||||||
|
if(Context.MoreTokens)
|
||||||
|
body = ParseNode();
|
||||||
|
|
||||||
|
return new ForLoopNode(init,condition,inc,body);
|
||||||
|
}
|
||||||
|
else if(token.Text == "each")
|
||||||
|
{
|
||||||
|
SymbolNode varNode = new GetVariableNode("item"){LineInfo = token.Position};
|
||||||
|
Node expr = ParseNode();
|
||||||
|
|
||||||
|
if(Context.NextEntries(true,":").Success)
|
||||||
|
{
|
||||||
|
var vNode = expr as SymbolNode;
|
||||||
|
if(vNode != null)
|
||||||
|
{
|
||||||
|
varNode = vNode;
|
||||||
|
}
|
||||||
|
expr = ParseNode();
|
||||||
|
|
||||||
|
}
|
||||||
|
Context.NextEntries(true,")");
|
||||||
|
if(Context.MoreTokens)
|
||||||
|
{
|
||||||
|
return new EachLoopNode(varNode,expr,ParseNode()){LineInfo = token.Position};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(token.Text == "switch")
|
||||||
|
{
|
||||||
|
Node cond = ParseNode();
|
||||||
|
Context.NextEntries(true,")");
|
||||||
|
Node body = new Node();
|
||||||
|
if(!Context.NextEntries(true,";").Success)
|
||||||
|
{
|
||||||
|
body = ParseNode();
|
||||||
|
}
|
||||||
|
var scopeBody = body as ScopeNode;
|
||||||
|
if(scopeBody != null)
|
||||||
|
{
|
||||||
|
scopeBody.IsSwitchScope=true;
|
||||||
|
scopeBody.SwitchCondition = cond;
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
else if(token.Text == "while" || token.Text == "do")
|
||||||
|
{
|
||||||
|
Node cond = ParseNode();
|
||||||
|
Context.NextEntries(true,")");
|
||||||
|
Node body = new Node();
|
||||||
|
if(!Context.NextEntries(true,";").Success)
|
||||||
|
{
|
||||||
|
body = ParseNode();
|
||||||
|
}
|
||||||
|
return new WhileLoop(cond,body,token.Text == "do");
|
||||||
|
}
|
||||||
|
else if(token.Text == "if")
|
||||||
|
{
|
||||||
|
Node cond = ParseNode();
|
||||||
|
Context.NextEntries(true,")");
|
||||||
|
Node yes = new Node();
|
||||||
|
Node no = new Node();
|
||||||
|
if(Context.MoreTokens && !Context.NextEntries(false,"else").Success)
|
||||||
|
{
|
||||||
|
yes = ParseNode();
|
||||||
|
}
|
||||||
|
if(Context.MoreTokens && Context.NextEntries(true,"else").Success)
|
||||||
|
{
|
||||||
|
no = ParseNode();
|
||||||
|
}
|
||||||
|
return new IfNode(cond,yes,no);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var fcall = new FunctionCallNode(token.Text){LineInfo = token.Position};
|
||||||
|
SymbolNode ret = fcall;
|
||||||
|
while(Context.MoreTokens && !Context.NextEntries(true,")").Success)
|
||||||
|
{
|
||||||
|
if(Context.NextEntries(true,",").Success) continue;
|
||||||
|
fcall.Arguments.Add(ParseNode());
|
||||||
|
}
|
||||||
|
while(Context.MoreTokens && Context.NextEntries(true,"[").Success)
|
||||||
|
{
|
||||||
|
var p = ParseNode();
|
||||||
|
ret = new GetArrayNode(ret,p){LineInfo = p.LineInfo};
|
||||||
|
Context.NextEntries(true,"]");
|
||||||
|
}
|
||||||
|
while(Context.MoreTokens && Context.NextEntries(true,".").Success)
|
||||||
|
{
|
||||||
|
var token2 = Context.NextEntry;
|
||||||
|
|
||||||
|
if(Context.MoreTokens && Context.NextEntries(true,"(").Success)
|
||||||
|
{
|
||||||
|
var mCall = new MethodCallNode(ret,token2.Text){LineInfo=token2.Position};
|
||||||
|
ret = mCall;
|
||||||
|
while(Context.MoreTokens && !Context.NextEntries(true,")").Success)
|
||||||
|
{
|
||||||
|
if(Context.NextEntries(true,",").Success) continue;
|
||||||
|
mCall.Arguments.Add(ParseNode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(Context.MoreTokens && Context.NextEntries(false,"[").Success)
|
||||||
|
{
|
||||||
|
while(Context.MoreTokens && Context.NextEntries(true,"[").Success)
|
||||||
|
{
|
||||||
|
var p = ParseNode();
|
||||||
|
ret = new GetArrayNode(ret,p){LineInfo = p.LineInfo};
|
||||||
|
Context.NextEntries(true,"]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = new GetMemberNode(ret,token2.Text){LineInfo = token2.Position};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(Context.MoreTokens && Context.NextEntries(true,"++").Success)
|
||||||
|
{
|
||||||
|
var r = new PostFixIncrementNode(ret){LineInfo = ret.LineInfo};
|
||||||
|
ret = r;
|
||||||
|
}
|
||||||
|
if(Context.MoreTokens && Context.NextEntries(true,"--").Success)
|
||||||
|
{
|
||||||
|
var r = new PostFixDecrementNode(ret){LineInfo = ret.LineInfo};
|
||||||
|
ret = r;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Node ret = new Node();
|
||||||
|
if(token.Text == "func")
|
||||||
|
{
|
||||||
|
var res = new GetVariableNode(Context.NextEntry.Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new CompilerError("End of ParseValue func",new Node(){LineInfo = token.Position});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ClassEntryNode : Node
|
||||||
|
{
|
||||||
|
public string Name {get;set;}="";
|
||||||
|
public string Modifier {get;set;}="";
|
||||||
|
|
||||||
|
public string Documentation {get;set;}="";
|
||||||
|
public Node InitialValue {get;set;}=new Node();
|
||||||
|
public bool Abstract { get; set; }=false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ClassNode : Node
|
||||||
|
{
|
||||||
|
public string Documentation {get;set;}
|
||||||
|
public string Name {get;set;}
|
||||||
|
public string InheritsFrom {get;set;}="object";
|
||||||
|
|
||||||
|
public List<ClassEntryNode> Entries {get;set;}=new List<ClassEntryNode>();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ClosureNode : Node
|
||||||
|
{
|
||||||
|
public List<string> Arguments {get;set;}
|
||||||
|
public Node Node {get;set;}
|
||||||
|
|
||||||
|
public ClosureNode(List<string> args, Node node)
|
||||||
|
{
|
||||||
|
Arguments = args;
|
||||||
|
Node = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class CompilerError : Exception
|
||||||
|
{
|
||||||
|
private string ErrorMessage {get;set;}
|
||||||
|
private Node CurrentNode {get;set;}
|
||||||
|
|
||||||
|
public CompilerError()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompilerError(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompilerError(string v, Node node) : base(GenerateMessage(v,node))
|
||||||
|
{
|
||||||
|
this.ErrorMessage = v;
|
||||||
|
this.CurrentNode = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GenerateMessage(string v, Node node)
|
||||||
|
{
|
||||||
|
return $"Compiler Error {node.LineInfo}: {v}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompilerError(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompilerError(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ConstNumberNode : Node
|
||||||
|
{
|
||||||
|
public double Value {get;set;}
|
||||||
|
|
||||||
|
public ConstNumberNode(double number2)
|
||||||
|
{
|
||||||
|
this.Value = number2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ContinueNode : Node
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class DefaultNode : Node
|
||||||
|
{
|
||||||
|
public Node Node {get;set;}
|
||||||
|
|
||||||
|
public DefaultNode(Node node)
|
||||||
|
{
|
||||||
|
Node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class DivideNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public DivideNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class EachLoopNode : Node
|
||||||
|
{
|
||||||
|
public SymbolNode Name {get;set;}
|
||||||
|
public Node Itterator {get;set;}
|
||||||
|
public Node Body {get;set;}
|
||||||
|
|
||||||
|
public EachLoopNode(SymbolNode varNode, Node expr, Node node)
|
||||||
|
{
|
||||||
|
Name = varNode;
|
||||||
|
Itterator = expr;
|
||||||
|
Body = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class EqualsNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public EqualsNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ForLoopNode : Node
|
||||||
|
{
|
||||||
|
public Node Init {get;set;}
|
||||||
|
public Node Condition {get;set;}
|
||||||
|
public Node Increment {get;set;}
|
||||||
|
public Node Body {get;set;}
|
||||||
|
|
||||||
|
public ForLoopNode(Node init, Node condition, Node inc, Node body)
|
||||||
|
{
|
||||||
|
Init = init;
|
||||||
|
Condition = condition;
|
||||||
|
Increment = inc;
|
||||||
|
Body = body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class FunctionCallNode : CallNode
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public FunctionCallNode(string text)
|
||||||
|
{
|
||||||
|
Name = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class GetArrayNode : SymbolNode
|
||||||
|
{
|
||||||
|
public SymbolNode Symbol {get;set;}
|
||||||
|
public Node Expression {get;set;}
|
||||||
|
|
||||||
|
public GetArrayNode(SymbolNode sym, Node expr)
|
||||||
|
{
|
||||||
|
Symbol = sym;
|
||||||
|
this.Name = sym.Name;
|
||||||
|
Expression = expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
internal class GetMemberNode : SymbolNode
|
||||||
|
{
|
||||||
|
public SymbolNode Symbol {get;set;}
|
||||||
|
|
||||||
|
public GetMemberNode(SymbolNode symbol, string name)
|
||||||
|
{
|
||||||
|
Symbol = symbol;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class GetVariableNode : SymbolNode
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public GetVariableNode(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class GreaterThanEqualsNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public GreaterThanEqualsNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class GreaterThanNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public GreaterThanNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
internal class IfNode : Node
|
||||||
|
{
|
||||||
|
public Node Condition {get;set;}
|
||||||
|
public Node Yes {get;set;}
|
||||||
|
public Node No {get;set;}
|
||||||
|
|
||||||
|
public IfNode(Node cond, Node yes, Node no)
|
||||||
|
{
|
||||||
|
Condition = cond;
|
||||||
|
Yes = yes;
|
||||||
|
No = no;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class LAndNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public LAndNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class LOrNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public LOrNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class LeftShiftNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public LeftShiftNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class LessThanEqualsNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public LessThanEqualsNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class LessThanNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public LessThanNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class MethodCallNode : SymbolNode
|
||||||
|
{
|
||||||
|
public SymbolNode Symbol {get;set;}
|
||||||
|
public List<Node> Arguments {get;set;}=new List<Node>();
|
||||||
|
|
||||||
|
public MethodCallNode(SymbolNode symbol, string name)
|
||||||
|
{
|
||||||
|
Symbol = symbol;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ModuloNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public ModuloNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class MultiplyNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public MultiplyNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class NegativeNode : Node
|
||||||
|
{
|
||||||
|
public Node Node {get;set;}
|
||||||
|
|
||||||
|
public NegativeNode(Node node)
|
||||||
|
{
|
||||||
|
Node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class Node
|
||||||
|
{
|
||||||
|
public LexLineInfo LineInfo {get;set;}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class NotEqualsNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public NotEqualsNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using TLang.Lexer;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class NotNode : Node
|
||||||
|
{
|
||||||
|
public Node Node {get;set;}
|
||||||
|
|
||||||
|
public NotNode(Node node)
|
||||||
|
{
|
||||||
|
Node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class PostFixDecrementNode : SymbolNode
|
||||||
|
{
|
||||||
|
public SymbolNode SymbolNode {get;set;}
|
||||||
|
|
||||||
|
public PostFixDecrementNode(SymbolNode symbol)
|
||||||
|
{
|
||||||
|
SymbolNode = symbol;
|
||||||
|
Name = symbol.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class PostFixIncrementNode : SymbolNode
|
||||||
|
{
|
||||||
|
public SymbolNode SymbolNode {get;set;}
|
||||||
|
|
||||||
|
public PostFixIncrementNode(SymbolNode symbol)
|
||||||
|
{
|
||||||
|
SymbolNode = symbol;
|
||||||
|
Name = symbol.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class PowNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public PowNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ReturnNode : Node
|
||||||
|
{
|
||||||
|
public Node Expression {get;set;}
|
||||||
|
|
||||||
|
public ReturnNode(Node node)
|
||||||
|
{
|
||||||
|
Expression = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class RightShiftNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public RightShiftNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class ScopeNode : Node
|
||||||
|
{
|
||||||
|
public bool IsSwitchScope {get;set;}
|
||||||
|
public Node SwitchCondition {get;set;}=new Node();
|
||||||
|
public List<Node> Nodes {get;set;}=new List<Node>();
|
||||||
|
public void Add(Node node)
|
||||||
|
{
|
||||||
|
Nodes.Add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class SetVariableNode : SymbolNode
|
||||||
|
{
|
||||||
|
|
||||||
|
public Node Expression {get;set;}
|
||||||
|
|
||||||
|
public SetVariableNode(string name, Node expr)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Expression = expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class StringNode : Node
|
||||||
|
{
|
||||||
|
public string Text {get;set;}
|
||||||
|
|
||||||
|
public StringNode(string text)
|
||||||
|
{
|
||||||
|
Text = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class SubtractNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public SubtractNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class SymbolNode : Node
|
||||||
|
{
|
||||||
|
public string Name {get;set;}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\TLang.Lexer\TLang.Lexer.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,17 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class WhileLoop : Node
|
||||||
|
{
|
||||||
|
public Node Condition {get;set;}
|
||||||
|
public Node Body {get;set;}
|
||||||
|
|
||||||
|
public bool IsDo {get;set;}
|
||||||
|
|
||||||
|
public WhileLoop(Node cond, Node body, bool v)
|
||||||
|
{
|
||||||
|
Condition = cond;
|
||||||
|
Body = body;
|
||||||
|
IsDo = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace TLang.Parser
|
||||||
|
{
|
||||||
|
public class XOrNode : Node
|
||||||
|
{
|
||||||
|
private Node Left {get;set;}
|
||||||
|
private Node Right {get;set;}
|
||||||
|
|
||||||
|
public XOrNode(Node left, Node right)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue