Doing some tests
This commit is contained in:
parent
8a3a0ade1f
commit
fd49fbc3c5
BIN
.vs/DialogueManagementScript/v16/.suo
Normal file
BIN
.vs/DialogueManagementScript/v16/.suo
Normal file
Binary file not shown.
BIN
.vs/DialogueManagementScript/v16/Browse.VC.db
Normal file
BIN
.vs/DialogueManagementScript/v16/Browse.VC.db
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
31
DialogueManagementScript.sln
Normal file
31
DialogueManagementScript.sln
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29911.84
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DialogueManagementScript", "DialogueManagementScript\DialogueManagementScript.vcxproj", "{709C242E-2FB4-462A-88F5-009D903C463F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{709C242E-2FB4-462A-88F5-009D903C463F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{709C242E-2FB4-462A-88F5-009D903C463F}.Debug|x64.Build.0 = Debug|x64
|
||||
{709C242E-2FB4-462A-88F5-009D903C463F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{709C242E-2FB4-462A-88F5-009D903C463F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{709C242E-2FB4-462A-88F5-009D903C463F}.Release|x64.ActiveCfg = Release|x64
|
||||
{709C242E-2FB4-462A-88F5-009D903C463F}.Release|x64.Build.0 = Release|x64
|
||||
{709C242E-2FB4-462A-88F5-009D903C463F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{709C242E-2FB4-462A-88F5-009D903C463F}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3F3B7427-4F15-495C-8609-9A4FB78D9127}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
20
DialogueManagementScript/DialogueManagementScript.cpp
Normal file
20
DialogueManagementScript/DialogueManagementScript.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
// DialogueManagementScript.cpp : This file contains the 'main' function. Program execution begins and ends there.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Hello World!\n";
|
||||
}
|
||||
|
||||
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
|
||||
// Debug program: F5 or Debug > Start Debugging menu
|
||||
|
||||
// Tips for Getting Started:
|
||||
// 1. Use the Solution Explorer window to add/manage files
|
||||
// 2. Use the Team Explorer window to connect to source control
|
||||
// 3. Use the Output window to see build output and other messages
|
||||
// 4. Use the Error List window to view errors
|
||||
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
|
||||
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
|
||||
159
DialogueManagementScript/DialogueManagementScript.vcxproj
Normal file
159
DialogueManagementScript/DialogueManagementScript.vcxproj
Normal file
@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{709C242E-2FB4-462A-88F5-009D903C463F}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>DialogueManagementScript</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DialogueManagementScript.cpp" />
|
||||
<ClCompile Include="Token.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Token.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DialogueManagementScript.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Token.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Token.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
1
DialogueManagementScript/Token.cpp
Normal file
1
DialogueManagementScript/Token.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "Token.h"
|
||||
5
DialogueManagementScript/Token.h
Normal file
5
DialogueManagementScript/Token.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
class Token
|
||||
{
|
||||
};
|
||||
|
||||
424
compiler.lua
424
compiler.lua
@ -1,21 +1,30 @@
|
||||
--~ t = debug.getmetatable ("")
|
||||
--~ t.__index = function(self,k)
|
||||
--~ if type(k)=="number" then
|
||||
--~ return string.sub(self,k,k)
|
||||
--~ end
|
||||
--~ end
|
||||
function tprint (tbl, indent)
|
||||
if not indent then indent = 0 end
|
||||
for k, v in pairs(tbl) do
|
||||
formatting = string.rep(" ", indent) .. k .. ": "
|
||||
if type(v) == "table" then
|
||||
print(formatting)
|
||||
tprint(v, indent+1)
|
||||
else
|
||||
print(formatting .. tostring(v))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Token = {}
|
||||
Token.__index = Token
|
||||
local INTEGER, PLUS, EOF, MINUS, MUL, DIV, LPAREN, RPAREN = "INT","+","EOF", "-", "*", "/", "(", ")"
|
||||
local INTEGER, PLUS, EOF, MINUS, MUL, DIV, LPAREN, RPAREN, BEGIN, END, DOT, ID, ASSIGN, SEMI = "INT","+","EOF", "-", "*", "/", "(", ")", "BEGIN", "END", "DOT", "ID", "ASSIGN", "SEMI"
|
||||
function Token.__tostring(self)
|
||||
return string.format("Token(%s, %s)",self.type,self.value)
|
||||
end
|
||||
function Token:new(tp,val)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'Token'
|
||||
c.type = tp
|
||||
c.value = val
|
||||
print("Token:"..tp)
|
||||
--print("Token:"..tp)
|
||||
return c
|
||||
end
|
||||
|
||||
@ -24,22 +33,45 @@ Lexer.__index = Lexer
|
||||
function Lexer:new(text)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
self.text = text
|
||||
self.pos = 1
|
||||
self.current_char = self.text:sub(1,1)
|
||||
self.stop = false
|
||||
c.Type = 'Lexer'
|
||||
c.text = text
|
||||
c.pos = 1
|
||||
c.current_char = c.text:sub(1,1)
|
||||
c.stop = false
|
||||
return c
|
||||
end
|
||||
function Lexer:advance()
|
||||
self.pos = self.pos + 1
|
||||
if self.pos > #self.text then
|
||||
self.current_char = false
|
||||
return
|
||||
else
|
||||
self.current_char = self.text:sub(self.pos,self.pos)
|
||||
end
|
||||
end
|
||||
function Lexer:error()
|
||||
error("Invalid character")
|
||||
local RESERVED_KEYWORDS = {
|
||||
BEGIN = Token:new('BEGIN',BEGIN),
|
||||
END = Token:new('END',END)
|
||||
}
|
||||
function Lexer:_id()
|
||||
local result = ''
|
||||
while self.current_char and self.current_char:match("%w") do
|
||||
result = result .. self.current_char
|
||||
self:advance()
|
||||
end
|
||||
local token = RESERVED_KEYWORDS[result] or Token:new(ID,result)
|
||||
return token
|
||||
end
|
||||
function Lexer:peek()
|
||||
local peek_pos = self.pos + 1
|
||||
if peek_pos > #self.text then
|
||||
return
|
||||
else
|
||||
return self.text:sub(peek_pos,peek_pos)
|
||||
end
|
||||
end
|
||||
function Lexer:error(err)
|
||||
error(err)
|
||||
end
|
||||
function Lexer:skip_whitespace()
|
||||
while self.current_char and self.current_char:match("%s") do
|
||||
@ -57,110 +89,392 @@ end
|
||||
function Lexer:get_next_token()
|
||||
while self.current_char do
|
||||
::continue::
|
||||
if self.current_char:match("%s") then
|
||||
if self.current_char and self.current_char:match("%s") then
|
||||
self:skip_whitespace()
|
||||
goto continue
|
||||
end
|
||||
if self.current_char:match("%d") then
|
||||
if self.current_char and self.current_char:match("%d") then
|
||||
return Token:new(INTEGER,self:integer())
|
||||
end
|
||||
if self.current_char == "+" then
|
||||
if self.current_char and self.current_char == "+" then
|
||||
self:advance()
|
||||
return Token:new(PLUS,"+")
|
||||
end
|
||||
if self.current_char == "-" then--55+77
|
||||
if self.current_char and self.current_char == "-" then--55+77
|
||||
self:advance()
|
||||
return Token:new(MINUS,"-")
|
||||
end
|
||||
if self.current_char == "*" then
|
||||
if self.current_char and self.current_char == "*" then
|
||||
self:advance()
|
||||
return Token:new(MUL,"*")
|
||||
end
|
||||
if self.current_char == "/" then
|
||||
if self.current_char and self.current_char == "/" then
|
||||
self:advance()
|
||||
return Token:new(DIV,"/")
|
||||
end
|
||||
if self.current_char == "(" then
|
||||
if self.current_char and self.current_char == "(" then
|
||||
self:advance()
|
||||
return Token:new(LPAREN,"(")
|
||||
end
|
||||
if self.current_char == ")" then
|
||||
if self.current_char and self.current_char == ")" then
|
||||
self:advance()
|
||||
return Token:new(RPAREN,")")
|
||||
end
|
||||
self:error("Invalid Symbol!")
|
||||
if self.current_char and self.current_char:match("%w") then
|
||||
return self:_id()
|
||||
end
|
||||
if self.current_char and self.current_char == ":" and self:peek() == "=" then
|
||||
self:advance()
|
||||
self:advance()
|
||||
return Token:new(ASSIGN, ":=")
|
||||
end
|
||||
if self.current_char and self.current_char == ";" then
|
||||
self:advance()
|
||||
return Token:new(SEMI, ';')
|
||||
end
|
||||
if self.current_char and self.current_char == "." then
|
||||
self:advance()
|
||||
return Token:new(DOT,".")
|
||||
end
|
||||
if self.current_char == false then
|
||||
return Token:new(EOF, "EOF")
|
||||
end
|
||||
self:error("Invalid Symbol! "..tostring(self.current_char))
|
||||
end
|
||||
return Token:new(EOF, nil)
|
||||
return Token:new(EOF, "EOF")
|
||||
end
|
||||
|
||||
Interpreter = {}
|
||||
Interpreter.__index = Interpreter
|
||||
function Interpreter:new(lexer)
|
||||
AST = {}
|
||||
AST.__index = AST
|
||||
function AST:new()
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.lexer = lexer
|
||||
c.current_token = c.lexer:get_next_token()
|
||||
c.Type = 'AST'
|
||||
return c
|
||||
end
|
||||
function Interpreter:error()
|
||||
|
||||
Compound = {}
|
||||
Compound.__index = AST
|
||||
function Compound:new()
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'Compound'
|
||||
c.children = {}
|
||||
return c
|
||||
end
|
||||
|
||||
Assign = {}
|
||||
Assign.__index = AST
|
||||
function Assign:new(left,op,right)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'Assign'
|
||||
c.left = left
|
||||
c.op = op
|
||||
c.token = op
|
||||
c.right = right
|
||||
return c
|
||||
end
|
||||
|
||||
Var = {}
|
||||
Var.__index = AST
|
||||
function Var:new(token)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = "Var"
|
||||
c.token = token
|
||||
c.value = token.value
|
||||
return c
|
||||
end
|
||||
|
||||
NoOp = {}
|
||||
NoOp.__index = AST
|
||||
function NoOp:new()
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = "NoOp"
|
||||
return c
|
||||
end
|
||||
|
||||
UnaryOp = {}
|
||||
UnaryOp.__index = AST
|
||||
function UnaryOp:new(op,expr)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'UnaryOp'
|
||||
c.token = op
|
||||
c.op = op
|
||||
c.expr = expr
|
||||
return c
|
||||
end
|
||||
|
||||
BinOp = {}
|
||||
BinOp.__index = AST
|
||||
function BinOp:new(left, op, right)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'BinOp'
|
||||
c.left = left
|
||||
c.token = op
|
||||
c.op = op
|
||||
c.right = right
|
||||
return c
|
||||
end
|
||||
|
||||
Num = {}
|
||||
Num.__index = AST
|
||||
function Num:new(token)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'Num'
|
||||
c.token = token
|
||||
c.value = token.value
|
||||
return c
|
||||
end
|
||||
|
||||
Parser = {}
|
||||
Parser.__index = Parser
|
||||
function Parser:new(lexer)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'Parser'
|
||||
c.lexer = lexer
|
||||
c.current_token = lexer:get_next_token()
|
||||
return c
|
||||
end
|
||||
function Parser:error()
|
||||
error('Error Invalid Syntax')
|
||||
end
|
||||
function Interpreter:eat(token_type)
|
||||
function Parser:eat(token_type)
|
||||
if self.current_token.type == token_type then
|
||||
self.current_token = self.lexer:get_next_token()
|
||||
else
|
||||
self:error()
|
||||
end
|
||||
end
|
||||
function Interpreter:factor()
|
||||
function Parser:program()
|
||||
local node = self:compound_statement()
|
||||
self:eat(DOT)
|
||||
return node
|
||||
end
|
||||
function Parser:compound_statement()
|
||||
self:eat(BEGIN)
|
||||
local nodes = self:statement_list()
|
||||
self:eat(END)
|
||||
|
||||
local root = Compound:new()
|
||||
for _,node in pairs(nodes) do
|
||||
table.insert(root.children,node)
|
||||
end
|
||||
|
||||
return root
|
||||
end
|
||||
function Parser:statement_list()
|
||||
local node = self:statement()
|
||||
|
||||
local results = {node}
|
||||
|
||||
while self.current_token.type == SEMI do
|
||||
self:eat(SEMI)
|
||||
table.insert(results,self:statement())
|
||||
end
|
||||
|
||||
if self.current_token.type == ID then
|
||||
self:error()
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
function Parser:statement()
|
||||
local node
|
||||
if self.current_token.type == BEGIN then
|
||||
node = self:compound_statement()
|
||||
elseif self.current_token.type == ID then
|
||||
node = self:assignment_statement()
|
||||
else
|
||||
node = self:empty()
|
||||
end
|
||||
return node
|
||||
end
|
||||
function Parser:assignment_statement()
|
||||
local left = self:variable()
|
||||
local token = self.current_token
|
||||
if token.type == INTEGER then
|
||||
self:eat(ASSIGN)
|
||||
local right = self:expr()
|
||||
local node = Assign:new(left, token, right)
|
||||
return node
|
||||
end
|
||||
function Parser:variable()
|
||||
local node = Var:new(self.current_token)
|
||||
self:eat(ID)
|
||||
return node
|
||||
end
|
||||
function Parser:empty()
|
||||
return NoOp:new()
|
||||
end
|
||||
function Parser:factor()
|
||||
local token = self.current_token
|
||||
local node
|
||||
if token.type == PLUS then
|
||||
self:eat(PLUS)
|
||||
node = UnaryOp:new(token,self:factor())
|
||||
return node
|
||||
elseif token.type == MINUS then
|
||||
self:eat(MINUS)
|
||||
node = UnaryOp:new(token,self:factor())
|
||||
return node
|
||||
elseif token.type == INTEGER then
|
||||
self:eat(INTEGER)
|
||||
return token.value
|
||||
return Num:new(token)
|
||||
elseif token.type == LPAREN then
|
||||
self:eat(LPAREN)
|
||||
local result = self:expr()
|
||||
local node = self:expr()
|
||||
self:eat(RPAREN)
|
||||
return result
|
||||
return node
|
||||
else
|
||||
node = self:variable()
|
||||
return node
|
||||
end
|
||||
end
|
||||
function Interpreter:term()
|
||||
local result = self:factor()
|
||||
function Parser:term()
|
||||
local node = self:factor()
|
||||
local token
|
||||
while self.current_token.type == MUL or self.current_token.type == DIV do
|
||||
token = self.current_token
|
||||
if token.type == MUL then
|
||||
self:eat(MUL)
|
||||
result = result * self:factor()
|
||||
elseif token.type == DIV then
|
||||
self:eat(DIV)
|
||||
result = result / self:factor()
|
||||
end
|
||||
node = BinOp:new(node,token,self:factor())
|
||||
end
|
||||
return result
|
||||
|
||||
return node
|
||||
end
|
||||
function Interpreter:expr()
|
||||
local result = self:term()
|
||||
function Parser:expr()
|
||||
local node = self:term()
|
||||
local token
|
||||
while self.current_token.type == PLUS or self.current_token.type == MINUS do
|
||||
token = self.current_token
|
||||
if token.type == PLUS then
|
||||
self:eat(PLUS)
|
||||
result = result + self:term()
|
||||
elseif token.type == MINUS then
|
||||
self:eat(MINUS)
|
||||
result = result - self:term()
|
||||
end
|
||||
node = BinOp:new(node,token,self:term())
|
||||
end
|
||||
|
||||
return node
|
||||
end
|
||||
function Parser:parse()
|
||||
local node = self:program()
|
||||
if self.current_token.type ~= EOF then
|
||||
self:error()
|
||||
end
|
||||
return node
|
||||
end
|
||||
|
||||
NodeVisitor = {}
|
||||
NodeVisitor.__index = NodeVisitor
|
||||
function NodeVisitor:new(node)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'NodeVisitor'
|
||||
return c
|
||||
end
|
||||
function NodeVisitor:visit(node)
|
||||
local visitor = self["visit_".. node.Type] or self.generic_visit
|
||||
return visitor(self,node)
|
||||
end
|
||||
function NodeVisitor:generic_visit(node)
|
||||
error("No visit_"..node.Type.." method")
|
||||
end
|
||||
|
||||
Interpreter = {}
|
||||
Interpreter.__index = NodeVisitor
|
||||
function Interpreter:new(parser)
|
||||
local c = {}
|
||||
setmetatable(c,self)
|
||||
c.Type = 'Interpreter'
|
||||
c.parser = parser
|
||||
c.GLOBAL_SCOPE = {}
|
||||
function c:visit_Compound(node)
|
||||
for _,child in pairs(node.children) do
|
||||
self:visit(child)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
while true do
|
||||
io.write("calc> ")
|
||||
local text = io.read()
|
||||
if text then
|
||||
l = Lexer:new(text)
|
||||
i = Interpreter:new(l)
|
||||
result = i:expr()
|
||||
print(result)
|
||||
function c:visit_Assign(node)
|
||||
local var_name = node.left.value
|
||||
self.GLOBAL_SCOPE[var_name] = self:visit(node.right)
|
||||
end
|
||||
function c:visit_Var(node)
|
||||
local var_name = node.value
|
||||
local val = self.GLOBAL_SCOPE[var_name]
|
||||
if val then
|
||||
return val
|
||||
else
|
||||
error("NameError:"..var_name)
|
||||
end
|
||||
end
|
||||
function c:visit_NoOp(node)
|
||||
return
|
||||
end
|
||||
function c:visit_BinOp(node)
|
||||
if node.op.type == PLUS then
|
||||
return self:visit(node.left) + self:visit(node.right)
|
||||
elseif node.op.type == MINUS then
|
||||
return self:visit(node.left) - self:visit(node.right)
|
||||
elseif node.op.type == MUL then
|
||||
return self:visit(node.left) * self:visit(node.right)
|
||||
elseif node.op.type == DIV then
|
||||
return self:visit(node.left) / self:visit(node.right)
|
||||
end
|
||||
end
|
||||
function c:visit_UnaryOp(node)
|
||||
local op = node.op.type
|
||||
if op == PLUS then
|
||||
return self:visit(node.expr)
|
||||
elseif op == MINUS then
|
||||
return -self:visit(node.expr)
|
||||
end
|
||||
end
|
||||
function c:visit_Num(node)
|
||||
return node.value
|
||||
end
|
||||
function c:interpret()
|
||||
local tree = self.parser:parse()
|
||||
return self:visit(tree)
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
text = [[
|
||||
BEGIN
|
||||
BEGIN
|
||||
number := 2;
|
||||
a := number;
|
||||
b := 10 * a + 10 * number / 4;
|
||||
c := a - - b
|
||||
END;
|
||||
x := 11;
|
||||
END.
|
||||
]]
|
||||
lexer = Lexer:new(text)
|
||||
parser = Parser:new(lexer)
|
||||
interpreter = Interpreter:new(parser)
|
||||
tprint(parser)
|
||||
-- interpreter:interpret()
|
||||
-- for i,v in pairs(interpreter.GLOBAL_SCOPE) do
|
||||
-- print(i,v)
|
||||
-- end
|
||||
-- while true do
|
||||
-- io.write("calc> ")
|
||||
-- local text = io.read()
|
||||
-- if text then
|
||||
-- lexer = Lexer:new(text)
|
||||
-- parser = Parser:new(lexer)
|
||||
-- interpreter = Interpreter:new(parser)
|
||||
-- result = interpreter:interpret()
|
||||
-- print(result)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
28
compiler2.lua
Normal file
28
compiler2.lua
Normal file
@ -0,0 +1,28 @@
|
||||
file = io.open("test.dms","rb")
|
||||
content = file:read("*a")
|
||||
line_num = 0
|
||||
function string:trim()
|
||||
return (self:gsub("^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
local choice
|
||||
for line in content:gmatch("(.-)\n") do
|
||||
line_num = line_num + 1
|
||||
line = line:trim()
|
||||
::back::
|
||||
if line:match("^%[[_:,%w%(%)]+%]") then
|
||||
print(line_num,"BLOCK_START",line)
|
||||
elseif line:match("choice%s+\".+\"%s*:") then
|
||||
print(line_num,"CHOICE_BLOCK",line)
|
||||
choice = true
|
||||
elseif choice then
|
||||
choice = false
|
||||
if line:match("\".*\"%s*[_:,%w%(%)]+%(.*%)") then
|
||||
print(line_num,"CHOICE_OPTION",line)
|
||||
choice = true
|
||||
else
|
||||
goto back
|
||||
end
|
||||
else
|
||||
print(line_num,line)
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user