ast stuff
This commit is contained in:
parent
f1668853dd
commit
60059e1091
@ -25,10 +25,24 @@ add_executable(
|
|||||||
src/Arguments.h
|
src/Arguments.h
|
||||||
src/Normalizer.cpp
|
src/Normalizer.cpp
|
||||||
src/Normalizer.h
|
src/Normalizer.h
|
||||||
src/ASTNode.cpp
|
src/AST/ASTNode.cpp
|
||||||
src/ASTNode.h
|
src/AST/ASTNode.h
|
||||||
|
src/AST/BinaryOpNode.cpp
|
||||||
|
src/AST/BinaryOpNode.h
|
||||||
|
src/AST/ExprNode.cpp
|
||||||
|
src/AST/ExprNode.h
|
||||||
|
src/AST/MulNode.cpp
|
||||||
|
src/AST/MulNode.h
|
||||||
|
src/AST/NumberNode.cpp
|
||||||
|
src/AST/NumberNode.h
|
||||||
|
src/AST/StatementNode.cpp
|
||||||
|
src/AST/StatementNode.h
|
||||||
|
src/AST/SumNode.cpp
|
||||||
|
src/AST/SumNode.h
|
||||||
src/replace.cpp
|
src/replace.cpp
|
||||||
src/replace.h
|
src/replace.h
|
||||||
|
src/Parser.cpp
|
||||||
|
src/Parser.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(sapphirec PUBLIC src)
|
target_include_directories(sapphirec PUBLIC src)
|
||||||
|
11
core/__internal/allocate/linux.sp
Normal file
11
core/__internal/allocate/linux.sp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace allocate {
|
||||||
|
|
||||||
|
@memalloc (void*) (u64 size) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@memfree (void* ptr) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,5 +19,4 @@ namespace linux {
|
|||||||
@sys_exit (i32 code) {
|
@sys_exit (i32 code) {
|
||||||
syscall1(60,code);
|
syscall1(60,code);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
1
core/allocate.sp
Normal file
1
core/allocate.sp
Normal file
@ -0,0 +1 @@
|
|||||||
|
import core/__internal/allocate/linux;
|
@ -1,3 +1,5 @@
|
|||||||
|
import core/allocate;
|
||||||
|
|
||||||
namespace string {
|
namespace string {
|
||||||
|
|
||||||
@len (u64) (str string) {
|
@len (u64) (str string) {
|
||||||
@ -14,7 +16,7 @@ namespace string {
|
|||||||
u64 len_a = len(a);
|
u64 len_a = len(a);
|
||||||
u64 len_b = len(b);
|
u64 len_b = len(b);
|
||||||
u64 final_size = len_a + len_b;
|
u64 final_size = len_a + len_b;
|
||||||
i8* chars = i8*(final_size + 1); // TODO: work on allocation
|
i8* chars = (i8*)allocate.memalloc(final_size + 1);
|
||||||
clone(a,chars,len_a);
|
clone(a,chars,len_a);
|
||||||
clone(b,chars + len_a,len_b);
|
clone(b,chars + len_a,len_b);
|
||||||
chars[final_size] = 0;
|
chars[final_size] = 0;
|
||||||
@ -24,7 +26,7 @@ namespace string {
|
|||||||
@clone (str string, i8* buffer, u64 max_copy_size) {
|
@clone (str string, i8* buffer, u64 max_copy_size) {
|
||||||
u64 chars_cloned = 0;
|
u64 chars_cloned = 0;
|
||||||
i8* ptr = (i8*)string;
|
i8* ptr = (i8*)string;
|
||||||
while(chars_cloned <= max_copy_size && ptr[chars_cloned] != 0)
|
while(chars_cloned <= max_copy_size and ptr[chars_cloned] != 0)
|
||||||
{
|
{
|
||||||
buffer[chars_cloned] = ptr[chars_cloned];
|
buffer[chars_cloned] = ptr[chars_cloned];
|
||||||
chars_cloned += 1;
|
chars_cloned += 1;
|
||||||
|
8
examples/float128.sp
Normal file
8
examples/float128.sp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import core/io;
|
||||||
|
import core/string;
|
||||||
|
|
||||||
|
@main {
|
||||||
|
f128 float1 = 234.6;
|
||||||
|
f128 float2 = 2934748348291930404.5;
|
||||||
|
io.outln(string.concat('Result is: ',(str)(float1 + float2)));
|
||||||
|
}
|
9
src/AST/ASTNode.cpp
Normal file
9
src/AST/ASTNode.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "ASTNode.h"
|
||||||
|
|
||||||
|
ASTNode::ASTNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode::~ASTNode()
|
||||||
|
{
|
||||||
|
}
|
9
src/AST/ASTNode.h
Normal file
9
src/AST/ASTNode.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class ASTNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ASTNode();
|
||||||
|
~ASTNode();
|
||||||
|
};
|
10
src/AST/BinaryOpNode.cpp
Normal file
10
src/AST/BinaryOpNode.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "BinaryOpNode.h"
|
||||||
|
|
||||||
|
BinaryOpNode::BinaryOpNode(std::shared_ptr<ExprNode> left,std::shared_ptr<ExprNode> right)
|
||||||
|
: left(left), right(right), ExprNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryOpNode::~BinaryOpNode()
|
||||||
|
{
|
||||||
|
}
|
12
src/AST/BinaryOpNode.h
Normal file
12
src/AST/BinaryOpNode.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ExprNode.h"
|
||||||
|
|
||||||
|
class BinaryOpNode : public ExprNode
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<ExprNode> left;
|
||||||
|
std::shared_ptr<ExprNode> right;
|
||||||
|
public:
|
||||||
|
BinaryOpNode(std::shared_ptr<ExprNode> left,std::shared_ptr<ExprNode> right);
|
||||||
|
~BinaryOpNode();
|
||||||
|
};
|
16
src/AST/ExprNode.cpp
Normal file
16
src/AST/ExprNode.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "ExprNode.h"
|
||||||
|
|
||||||
|
ExprNode::ExprNode(std::shared_ptr<ExprNode> child): child(child), ASTNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ExprNode::ExprNode(): ASTNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ExprNode::~ExprNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
11
src/AST/ExprNode.h
Normal file
11
src/AST/ExprNode.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ASTNode.h"
|
||||||
|
|
||||||
|
class ExprNode : public ASTNode
|
||||||
|
{
|
||||||
|
std::shared_ptr<ExprNode> child;
|
||||||
|
public:
|
||||||
|
ExprNode(std::shared_ptr<ExprNode> child);
|
||||||
|
ExprNode();
|
||||||
|
~ExprNode();
|
||||||
|
};
|
10
src/AST/MulNode.cpp
Normal file
10
src/AST/MulNode.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "MulNode.h"
|
||||||
|
|
||||||
|
MulNode::MulNode(std::shared_ptr<ExprNode> left,std::shared_ptr<ExprNode> right, char op)
|
||||||
|
: BinaryOpNode(left,right), op(op)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MulNode::~MulNode()
|
||||||
|
{
|
||||||
|
}
|
10
src/AST/MulNode.h
Normal file
10
src/AST/MulNode.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "BinaryOpNode.h"
|
||||||
|
|
||||||
|
class MulNode final : public BinaryOpNode
|
||||||
|
{
|
||||||
|
char op;
|
||||||
|
public:
|
||||||
|
MulNode(std::shared_ptr<ExprNode> left,std::shared_ptr<ExprNode> right, char op);
|
||||||
|
~MulNode();
|
||||||
|
};
|
2
src/AST/NumberNode.cpp
Normal file
2
src/AST/NumberNode.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include "NumberNode.h"
|
||||||
|
|
10
src/AST/NumberNode.h
Normal file
10
src/AST/NumberNode.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ExprNode.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class NumberNode : public ExprNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NumberNode();
|
||||||
|
~NumberNode();
|
||||||
|
};
|
11
src/AST/StatementNode.cpp
Normal file
11
src/AST/StatementNode.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include "StatementNode.h"
|
||||||
|
|
||||||
|
StatementNode::StatementNode(std::shared_ptr<ExprNode> child): child(child), ASTNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
StatementNode::~StatementNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
10
src/AST/StatementNode.h
Normal file
10
src/AST/StatementNode.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ExprNode.h"
|
||||||
|
|
||||||
|
class StatementNode : public ASTNode
|
||||||
|
{
|
||||||
|
std::shared_ptr<ExprNode> child;
|
||||||
|
public:
|
||||||
|
StatementNode(std::shared_ptr<ExprNode> child);
|
||||||
|
~StatementNode();
|
||||||
|
};
|
10
src/AST/SumNode.cpp
Normal file
10
src/AST/SumNode.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "SumNode.h"
|
||||||
|
|
||||||
|
SumNode::SumNode(std::shared_ptr<ExprNode> left,std::shared_ptr<ExprNode> right, char op)
|
||||||
|
: BinaryOpNode(left,right), op(op)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SumNode::~SumNode()
|
||||||
|
{
|
||||||
|
}
|
10
src/AST/SumNode.h
Normal file
10
src/AST/SumNode.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "BinaryOpNode.h"
|
||||||
|
|
||||||
|
class SumNode final : public BinaryOpNode
|
||||||
|
{
|
||||||
|
char op;
|
||||||
|
public:
|
||||||
|
SumNode(std::shared_ptr<ExprNode> left,std::shared_ptr<ExprNode> right, char op);
|
||||||
|
~SumNode();
|
||||||
|
};
|
@ -1,27 +0,0 @@
|
|||||||
#include "ASTNode.h"
|
|
||||||
|
|
||||||
ASTNode::ASTNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTNode::~ASTNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
BinaryOpNode::BinaryOpNode(std::shared_ptr<ASTNode> left,std::shared_ptr<ASTNode> right)
|
|
||||||
: left(left), right(right)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
BinaryOpNode::~BinaryOpNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PlusNode::PlusNode(std::shared_ptr<ASTNode> left,std::shared_ptr<ASTNode> right)
|
|
||||||
: BinaryOpNode(left,right)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PlusNode::~PlusNode()
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class ASTNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ASTNode();
|
|
||||||
~ASTNode();
|
|
||||||
};
|
|
||||||
|
|
||||||
class BinaryOpNode : public ASTNode
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
std::shared_ptr<ASTNode> left;
|
|
||||||
std::shared_ptr<ASTNode> right;
|
|
||||||
public:
|
|
||||||
BinaryOpNode(std::shared_ptr<ASTNode> left,std::shared_ptr<ASTNode> right);
|
|
||||||
~BinaryOpNode();
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlusNode final : public BinaryOpNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PlusNode(std::shared_ptr<ASTNode> left,std::shared_ptr<ASTNode> right);
|
|
||||||
~PlusNode();
|
|
||||||
};
|
|
@ -1,14 +1,29 @@
|
|||||||
#include "FileIO.h"
|
#include "FileIO.h"
|
||||||
|
#include "Error.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
std::string FileIO::read_all(const std::string& filename)
|
std::string FileIO::read_all(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::ifstream file(filename);
|
std::ifstream file;
|
||||||
if(!file.is_open()) return "";
|
file.exceptions(std::ios::badbit | std::ios::failbit);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
file.open(filename);
|
||||||
|
}
|
||||||
|
catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
Error::throw_error_without_location("unable to open file "+ filename + ": " + strerror(errno));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if(std::filesystem::is_directory(std::filesystem::status(filename))) Error::throw_error_without_location("unable to open file "+ filename + ": Is a directory");
|
||||||
|
file.exceptions(std::ios::goodbit);
|
||||||
std::vector<char> file_chars;
|
std::vector<char> file_chars;
|
||||||
char fchar;
|
char fchar;
|
||||||
while (file) {
|
while (file.good()) {
|
||||||
fchar = file.get();
|
fchar = file.get();
|
||||||
if(fchar != -1 ) file_chars.push_back(fchar);
|
if(fchar != -1 ) file_chars.push_back(fchar);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ TokenStream Importer::evaluate(const TokenStream& original)
|
|||||||
{
|
{
|
||||||
Token current_token = original[i];
|
Token current_token = original[i];
|
||||||
|
|
||||||
if(current_token.tk_type == TT_Keyword && current_token.string_value == Lexer::keywords[1])
|
if(current_token.tk_type == TT_Import)
|
||||||
{
|
{
|
||||||
Token next_token = original[i+1];
|
Token next_token = original[i+1];
|
||||||
if(next_token.tk_type == TT_EOF)
|
if(next_token.tk_type == TT_EOF)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#define IDENTIFIERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ_0123456789"
|
#define IDENTIFIERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ_0123456789"
|
||||||
#define DIGITS "0123456789"
|
#define DIGITS "0123456789"
|
||||||
|
|
||||||
const std::array<std::string,KEYWORD_COUNT> Lexer::keywords = {"var","import","out"};
|
const std::array<std::string,TYPE_COUNT> Lexer::types = {"void","bool","str","i8","i16","i32","i64","u8","u16","u32","u64","f32","f64","f128"};
|
||||||
|
|
||||||
Lexer::Lexer(const std::string& fname)
|
Lexer::Lexer(const std::string& fname)
|
||||||
: loc(1,0,fname), index(-1), prev_loc(1,0,fname)
|
: loc(1,0,fname), index(-1), prev_loc(1,0,fname)
|
||||||
@ -163,6 +163,12 @@ TokenStream Lexer::lex(const std::string& text)
|
|||||||
case '!':
|
case '!':
|
||||||
result.push_back(Token::make_with_line({TT_Exclamation,loc},current_line_text));
|
result.push_back(Token::make_with_line({TT_Exclamation,loc},current_line_text));
|
||||||
break;
|
break;
|
||||||
|
case '[':
|
||||||
|
result.push_back(Token::make_with_line({TT_Exclamation,loc},current_line_text));
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
result.push_back(Token::make_with_line({TT_Exclamation,loc},current_line_text));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Error::throw_error(loc,current_line_text,"unknown character");
|
Error::throw_error(loc,current_line_text,"unknown character");
|
||||||
}
|
}
|
||||||
@ -215,21 +221,36 @@ Token Lexer::create_identifier()
|
|||||||
this->rewind();
|
this->rewind();
|
||||||
std::string identifier(characters.begin(), characters.end());
|
std::string identifier(characters.begin(), characters.end());
|
||||||
if(is_path) return Token::make_with_line({TT_Path,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
if(is_path) return Token::make_with_line({TT_Path,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
auto location = std::find(keywords.begin(),keywords.end(),identifier);
|
auto location = std::find(types.begin(),types.end(),identifier);
|
||||||
if(location != keywords.end())
|
if(location != types.end())
|
||||||
{
|
{
|
||||||
return Token::make_with_line({TT_Keyword,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
return Token::make_with_line({TT_Type,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
}
|
}
|
||||||
|
if (identifier == "import") return Token::make_with_line({TT_Import,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall0") return Token::make_with_line({TT_Syscall0,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall1") return Token::make_with_line({TT_Syscall1,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall2") return Token::make_with_line({TT_Syscall2,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall3") return Token::make_with_line({TT_Syscall3,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall4") return Token::make_with_line({TT_Syscall4,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall5") return Token::make_with_line({TT_Syscall5,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
return Token::make_with_line({TT_Identifier,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
return Token::make_with_line({TT_Identifier,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string identifier(characters.begin(), characters.end());
|
std::string identifier(characters.begin(), characters.end());
|
||||||
auto location = std::find(keywords.begin(),keywords.end(),identifier);
|
if(is_path) return Token::make_with_line({TT_Path,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
if(location != keywords.end())
|
auto location = std::find(types.begin(),types.end(),identifier);
|
||||||
|
if(location != types.end())
|
||||||
{
|
{
|
||||||
return Token::make_with_line({TT_Keyword,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
return Token::make_with_line({TT_Type,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
}
|
}
|
||||||
|
if (identifier == "import") return Token::make_with_line({TT_Import,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall0") return Token::make_with_line({TT_Syscall0,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall1") return Token::make_with_line({TT_Syscall1,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall2") return Token::make_with_line({TT_Syscall2,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall3") return Token::make_with_line({TT_Syscall3,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall4") return Token::make_with_line({TT_Syscall4,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
|
if (identifier == "syscall5") return Token::make_with_line({TT_Syscall5,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
return Token::make_with_line({TT_Identifier,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
return Token::make_with_line({TT_Identifier,identifier,{prev_line,prev_column,loc.fname}},current_line_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
typedef std::vector<Token> TokenStream;
|
typedef std::vector<Token> TokenStream;
|
||||||
#define KEYWORD_COUNT 3
|
#define TYPE_COUNT 14
|
||||||
|
|
||||||
class Lexer
|
class Lexer
|
||||||
{
|
{
|
||||||
@ -34,7 +34,7 @@ private:
|
|||||||
|
|
||||||
bool is_in_string(const std::string& string, const char& character);
|
bool is_in_string(const std::string& string, const char& character);
|
||||||
public:
|
public:
|
||||||
static const std::array<std::string,KEYWORD_COUNT> keywords;
|
static const std::array<std::string,TYPE_COUNT> types;
|
||||||
~Lexer();
|
~Lexer();
|
||||||
|
|
||||||
TokenStream lex(const std::string& text);
|
TokenStream lex(const std::string& text);
|
||||||
|
9
src/Parser.cpp
Normal file
9
src/Parser.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "Parser.h"
|
||||||
|
|
||||||
|
Parser::Parser(/* args */)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::~Parser()
|
||||||
|
{
|
||||||
|
}
|
10
src/Parser.h
Normal file
10
src/Parser.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Parser
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
public:
|
||||||
|
Parser(/* args */);
|
||||||
|
~Parser();
|
||||||
|
};
|
@ -32,7 +32,17 @@ const std::string token_strings[] = {
|
|||||||
"TT_COMMA",
|
"TT_COMMA",
|
||||||
"TT_PATH",
|
"TT_PATH",
|
||||||
"TT_EXCLAMATION",
|
"TT_EXCLAMATION",
|
||||||
"TT_NEQUAL"
|
"TT_NEQUAL",
|
||||||
|
"TT_LSQB",
|
||||||
|
"TT_RSQB",
|
||||||
|
"TT_TYPE",
|
||||||
|
"TT_IMPORT",
|
||||||
|
"TT_SYSCALL0",
|
||||||
|
"TT_SYSCALL1",
|
||||||
|
"TT_SYSCALL2",
|
||||||
|
"TT_SYSCALL3",
|
||||||
|
"TT_SYSCALL4",
|
||||||
|
"TT_SYSCALL5"
|
||||||
};
|
};
|
||||||
|
|
||||||
Token::Token(const TokenType& type)
|
Token::Token(const TokenType& type)
|
||||||
@ -100,7 +110,11 @@ std::string Token::to_string() const
|
|||||||
else if (tk_type == TT_Keyword)
|
else if (tk_type == TT_Keyword)
|
||||||
{
|
{
|
||||||
return format_string("KEYWORD:%s %s",string_value,details);
|
return format_string("KEYWORD:%s %s",string_value,details);
|
||||||
}
|
}
|
||||||
|
else if (tk_type == TT_Type)
|
||||||
|
{
|
||||||
|
return format_string("TYPE:%s %s",string_value,details);
|
||||||
|
}
|
||||||
else if (tk_type == TT_String)
|
else if (tk_type == TT_String)
|
||||||
{
|
{
|
||||||
replace(const_cast<std::string&>(string_value),"\n","\\n");
|
replace(const_cast<std::string&>(string_value),"\n","\\n");
|
||||||
@ -154,6 +168,24 @@ std::string Token::to_string() const
|
|||||||
return "EXCLAMATION " + details;
|
return "EXCLAMATION " + details;
|
||||||
case TT_NEqual:
|
case TT_NEqual:
|
||||||
return "NEQUAL " + details;
|
return "NEQUAL " + details;
|
||||||
|
case TT_LSQB:
|
||||||
|
return "LEFTSQB " + details;
|
||||||
|
case TT_RSQB:
|
||||||
|
return "RIGHTSQB " + details;
|
||||||
|
case TT_Import:
|
||||||
|
return "IMPORT " + details;
|
||||||
|
case TT_Syscall0:
|
||||||
|
return "SYSCALL0 " + details;
|
||||||
|
case TT_Syscall1:
|
||||||
|
return "SYSCALL1 " + details;
|
||||||
|
case TT_Syscall2:
|
||||||
|
return "SYSCALL2 " + details;
|
||||||
|
case TT_Syscall3:
|
||||||
|
return "SYSCALL3 " + details;
|
||||||
|
case TT_Syscall4:
|
||||||
|
return "SYSCALL4 " + details;
|
||||||
|
case TT_Syscall5:
|
||||||
|
return "SYSCALL5 " + details;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
12
src/Token.h
12
src/Token.h
@ -33,7 +33,17 @@ enum TokenType
|
|||||||
TT_Comma,
|
TT_Comma,
|
||||||
TT_Path,
|
TT_Path,
|
||||||
TT_Exclamation,
|
TT_Exclamation,
|
||||||
TT_NEqual
|
TT_NEqual,
|
||||||
|
TT_LSQB,
|
||||||
|
TT_RSQB,
|
||||||
|
TT_Type,
|
||||||
|
TT_Import,
|
||||||
|
TT_Syscall0,
|
||||||
|
TT_Syscall1,
|
||||||
|
TT_Syscall2,
|
||||||
|
TT_Syscall3,
|
||||||
|
TT_Syscall4,
|
||||||
|
TT_Syscall5
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const std::string token_strings[];
|
extern const std::string token_strings[];
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
#include "TopLevelParser.h"
|
|
||||||
#include "Error.h"
|
|
||||||
|
|
||||||
TopLevelParseNode::TopLevelParseNode(const ParseContext& ctx, const TokenStream& tk_stream)
|
|
||||||
: context(ctx), tokens(tk_stream)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelParseNode::~TopLevelParseNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelParser::TopLevelParser()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelParser::~TopLevelParser()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TopLevelParseNode> TopLevelParser::ParseTokenStream(const TokenStream& stream)
|
|
||||||
{
|
|
||||||
current = stream;
|
|
||||||
index = -1;
|
|
||||||
std::vector<TopLevelParseNode> result;
|
|
||||||
|
|
||||||
while(index < current.size())
|
|
||||||
{
|
|
||||||
++index;
|
|
||||||
if(current[index].tk_type == TT_Keyword)
|
|
||||||
{
|
|
||||||
if(current[index].string_value == "var")
|
|
||||||
{
|
|
||||||
result.push_back(ParseGlobalVariable());
|
|
||||||
} else {
|
|
||||||
Error::throw_error(current[index].loc,current[index].line(),"global sections must start with var or @");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (current[index].tk_type == TT_At)
|
|
||||||
{
|
|
||||||
result.push_back(ParseFunctionDefinition());
|
|
||||||
} else {
|
|
||||||
Error::throw_error(current[index].loc,current[index].line(),"global sections must start with var or @");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelParseNode TopLevelParser::ParseGlobalVariable()
|
|
||||||
{
|
|
||||||
int prev_index = index;
|
|
||||||
if(!Token::match_token_types(current,{
|
|
||||||
{TT_Keyword},
|
|
||||||
{TT_Identifier},
|
|
||||||
{TT_LParen},
|
|
||||||
{TT_Identifier},
|
|
||||||
{TT_RParen}
|
|
||||||
},index))
|
|
||||||
{
|
|
||||||
Error::throw_error(current[index].loc,current[index].line(),"invalid syntax");
|
|
||||||
}
|
|
||||||
index += 5;
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Token.h"
|
|
||||||
#include "Lexer.h" //for TokenStream
|
|
||||||
|
|
||||||
enum ParseContext {
|
|
||||||
ParseContext_GlobalVariable,
|
|
||||||
ParseContext_FunctionDefinition
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TopLevelParseNode {
|
|
||||||
ParseContext context;
|
|
||||||
TokenStream tokens;
|
|
||||||
TopLevelParseNode(const ParseContext& ctx, const TokenStream& tk_stream);
|
|
||||||
~TopLevelParseNode();
|
|
||||||
};
|
|
||||||
|
|
||||||
class TopLevelParser
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
TokenStream current;
|
|
||||||
int index;
|
|
||||||
TopLevelParseNode ParseGlobalVariable();
|
|
||||||
TopLevelParseNode ParseFunctionDefinition();
|
|
||||||
public:
|
|
||||||
std::vector<TopLevelParseNode> ParseTokenStream(const TokenStream& stream);
|
|
||||||
TopLevelParser();
|
|
||||||
~TopLevelParser();
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user