Compare commits
No commits in common. "a0945e54b24ad8d052d6c58f1e20ae00b6c64b4a" and "dbd5627fe6029b827eff919b684abe2513edf033" have entirely different histories.
a0945e54b2
...
dbd5627fe6
@ -73,12 +73,6 @@ target_include_directories(sapphirec PUBLIC src)
|
||||
target_include_directories(sapphirec PUBLIC src/external/tclap-1.2.5/include)
|
||||
target_include_directories(sapphirec PUBLIC src/external)
|
||||
target_precompile_headers(sapphirec PUBLIC src/sapphirepch.h)
|
||||
set_property(TARGET sapphirec PROPERTY COMPILE_WARNING_AS_ERROR ON)
|
||||
|
||||
target_compile_options(sapphirec PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/W4>
|
||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic>
|
||||
)
|
||||
|
||||
llvm_map_components_to_libnames(llvm_libs all core support irreader x86asmparser x86codegen x86desc x86disassembler x86info x86targetmca aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "BinaryOpNode.h"
|
||||
|
||||
BinaryOpNode::BinaryOpNode(std::shared_ptr<ExprNode> left, std::shared_ptr<ExprNode> right)
|
||||
: ExprNode(), left(left), right(right)
|
||||
: left(left), right(right), ExprNode()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ EmptyFunctionNode::EmptyFunctionNode(FunctionPrototype prototype) : TopLevelNode
|
||||
{
|
||||
}
|
||||
|
||||
void EmptyFunctionNode::codegen([[maybe_unused]] IRBuilder* generator, llvm::Module* module)
|
||||
void EmptyFunctionNode::codegen(IRBuilder* generator, llvm::Module* module)
|
||||
{
|
||||
llvm::Function* Function = module->getFunction(prototype.name);
|
||||
if (!Function)
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "ExprNode.h"
|
||||
|
||||
ExprNode::ExprNode(std::shared_ptr<ExprNode> child) : ASTNode(), child(child)
|
||||
ExprNode::ExprNode(std::shared_ptr<ExprNode> child) : child(child), ASTNode()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "StatementNode.h"
|
||||
|
||||
StatementNode::StatementNode(std::shared_ptr<ExprNode> child) : ASTNode(), child(child)
|
||||
StatementNode::StatementNode(std::shared_ptr<ExprNode> child) : child(child), ASTNode()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,7 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InlineAsm.h"
|
||||
|
||||
// FIXME: This API is HIGHLY Linux-specific. The right thing to be done should be to expose an inline assembly expression, to do this kind of stuff freely
|
||||
// depending on the platform in core and any project that wants to use inline assembly, such as an OS kernel or embedded program :^)
|
||||
|
||||
Syscall0Node::Syscall0Node(int syscall_number) : ExprNode(), sys_num(syscall_number)
|
||||
Syscall0Node::Syscall0Node(int syscall_number) : sys_num(syscall_number), ExprNode()
|
||||
{
|
||||
}
|
||||
|
||||
@ -17,7 +14,7 @@ Syscall0Node::~Syscall0Node()
|
||||
}
|
||||
|
||||
Syscall1Node::Syscall1Node(int syscall_number, std::shared_ptr<ASTNode> arg1)
|
||||
: ExprNode(), sys_num(syscall_number), arg1(arg1)
|
||||
: sys_num(syscall_number), arg1(arg1), ExprNode()
|
||||
{
|
||||
}
|
||||
|
||||
@ -26,7 +23,7 @@ Syscall1Node::~Syscall1Node()
|
||||
}
|
||||
|
||||
Syscall2Node::Syscall2Node(int syscall_number, std::shared_ptr<ASTNode> arg1, std::shared_ptr<ASTNode> arg2)
|
||||
: ExprNode(), sys_num(syscall_number), arg1(arg1), arg2(arg2)
|
||||
: sys_num(syscall_number), arg1(arg1), arg2(arg2), ExprNode()
|
||||
{
|
||||
}
|
||||
|
||||
@ -36,7 +33,7 @@ Syscall2Node::~Syscall2Node()
|
||||
|
||||
Syscall3Node::Syscall3Node(int syscall_number, std::shared_ptr<ASTNode> arg1, std::shared_ptr<ASTNode> arg2,
|
||||
std::shared_ptr<ASTNode> arg3)
|
||||
: ExprNode(), sys_num(syscall_number), arg1(arg1), arg2(arg2), arg3(arg3)
|
||||
: sys_num(syscall_number), arg1(arg1), arg2(arg2), arg3(arg3), ExprNode()
|
||||
{
|
||||
}
|
||||
|
||||
@ -46,7 +43,7 @@ Syscall3Node::~Syscall3Node()
|
||||
|
||||
Syscall4Node::Syscall4Node(int syscall_number, std::shared_ptr<ASTNode> arg1, std::shared_ptr<ASTNode> arg2,
|
||||
std::shared_ptr<ASTNode> arg3, std::shared_ptr<ASTNode> arg4)
|
||||
: ExprNode(), sys_num(syscall_number), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4)
|
||||
: sys_num(syscall_number), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), ExprNode()
|
||||
{
|
||||
}
|
||||
|
||||
@ -56,7 +53,7 @@ Syscall4Node::~Syscall4Node()
|
||||
|
||||
Syscall5Node::Syscall5Node(int syscall_number, std::shared_ptr<ASTNode> arg1, std::shared_ptr<ASTNode> arg2,
|
||||
std::shared_ptr<ASTNode> arg3, std::shared_ptr<ASTNode> arg4, std::shared_ptr<ASTNode> arg5)
|
||||
: ExprNode(), sys_num(syscall_number), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5)
|
||||
: sys_num(syscall_number), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5), ExprNode()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "UnaryOpNode.h"
|
||||
|
||||
UnaryOpNode::UnaryOpNode(std::shared_ptr<ExprNode> operand) : ExprNode(), operand(operand)
|
||||
UnaryOpNode::UnaryOpNode(std::shared_ptr<ExprNode> operand) : operand(operand), ExprNode()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,6 @@ void Error::show_import_lines(const Location& loc, void (*import_line_printer)(c
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Seems like the cursor that indicates where the error is is a bit offset to the right.
|
||||
|
||||
[[noreturn]] void Error::throw_error(const Location& loc, const std::string line_text, const std::string& details)
|
||||
{
|
||||
show_import_lines(loc, show_import_line, std::cerr);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define IDENTIFIERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ_0123456789"
|
||||
#define DIGITS "0123456789"
|
||||
|
||||
Lexer::Lexer(const std::string& fname) : location(1, 0, fname), previous_location(1, 0, fname), index(-1)
|
||||
Lexer::Lexer(const std::string& fname) : location(1, 0, fname), index(-1), previous_location(1, 0, fname)
|
||||
{
|
||||
}
|
||||
|
||||
@ -17,10 +17,10 @@ Lexer::~Lexer()
|
||||
|
||||
int Lexer::advance()
|
||||
{
|
||||
previous_location = Location{ location };
|
||||
previous_location = location;
|
||||
++index;
|
||||
location.advance();
|
||||
if (index >= (ssize_t)current_lexed_text.size()) return 0;
|
||||
if (index >= current_lexed_text.size()) return 0;
|
||||
current_char = current_lexed_text[index];
|
||||
location.pos_from_char(current_char);
|
||||
if (current_char == '\n')
|
||||
@ -46,10 +46,10 @@ int Lexer::rewind()
|
||||
|
||||
std::string Lexer::recalculate_current_line(const std::string& text)
|
||||
{
|
||||
ssize_t idx = index;
|
||||
int idx = index;
|
||||
std::string final_str;
|
||||
++idx;
|
||||
while (idx != (ssize_t)text.size() && text[idx] != '\n')
|
||||
while (idx != text.size() && text[idx] != '\n')
|
||||
{
|
||||
final_str += text[idx];
|
||||
++idx;
|
||||
@ -106,7 +106,7 @@ TokenStream Lexer::lex(const std::string& text)
|
||||
switch (current_char)
|
||||
{
|
||||
case '/':
|
||||
if (index + 1 != (ssize_t)current_lexed_text.size())
|
||||
if (index + 1 != current_lexed_text.size())
|
||||
{
|
||||
if (current_lexed_text[index + 1] == '/')
|
||||
{
|
||||
@ -172,7 +172,7 @@ TokenStream Lexer::lex(const std::string& text)
|
||||
break;
|
||||
case '\377':
|
||||
result.push_back(Token(TT_EOF, location));
|
||||
return result;
|
||||
return std::move(result);
|
||||
default:
|
||||
Error::throw_error(location, current_line_text, "unknown character");
|
||||
}
|
||||
@ -180,7 +180,7 @@ TokenStream Lexer::lex(const std::string& text)
|
||||
|
||||
result.push_back(Token(TT_EOF, location));
|
||||
|
||||
return result;
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
Token Lexer::create_identifier()
|
||||
@ -303,7 +303,7 @@ Token Lexer::create_string()
|
||||
}
|
||||
if (current_char == '\\')
|
||||
{
|
||||
if (index + 1 == (ssize_t)current_lexed_text.size())
|
||||
if (index + 1 == current_lexed_text.size())
|
||||
{
|
||||
Error::throw_error(location, current_line_text, "unfinished escape sequence");
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ class Lexer
|
||||
int advance();
|
||||
int rewind();
|
||||
char current_char;
|
||||
ssize_t index;
|
||||
int index;
|
||||
|
||||
Lexer(const std::string& filename);
|
||||
|
||||
|
@ -30,19 +30,18 @@ void Location::pos_from_char(const char& character)
|
||||
}
|
||||
}
|
||||
|
||||
Location::Location(const Location& other)
|
||||
: line(other.line), column(other.column), filename(other.filename), parent(other.parent)
|
||||
{
|
||||
}
|
||||
|
||||
Location::Location(Location&& other)
|
||||
: line(other.line), column(other.column), filename(std::move(other.filename)), parent(std::move(other.parent))
|
||||
void Location::operator=(const Location& other)
|
||||
{
|
||||
Location copied = copy(other);
|
||||
line = copied.line;
|
||||
column = copied.column;
|
||||
parent = copied.parent;
|
||||
filename = std::move(copied.filename);
|
||||
}
|
||||
|
||||
Location Location::copy(const Location& other)
|
||||
{
|
||||
Location result(other.line, other.column, other.filename);
|
||||
result.parent = other.parent;
|
||||
return result;
|
||||
return std::move(result);
|
||||
}
|
||||
|
@ -14,14 +14,6 @@ struct Location
|
||||
/* Creates a Location with the given parameters. */
|
||||
Location(int line, int column, std::string filename);
|
||||
|
||||
Location(Location&& other);
|
||||
Location(const Location& other);
|
||||
|
||||
Location operator=(const Location& other)
|
||||
{
|
||||
return Location(other);
|
||||
}
|
||||
|
||||
~Location();
|
||||
|
||||
/* Returns a string of the format FILE:LINE:COL. */
|
||||
@ -33,6 +25,8 @@ struct Location
|
||||
/* Advance to the next line if provided a newline. */
|
||||
void pos_from_char(const char& character);
|
||||
|
||||
void operator=(const Location& other);
|
||||
|
||||
/* Returns a copy of the original Location. */
|
||||
static Location copy(const Location& other);
|
||||
};
|
||||
|
@ -37,7 +37,7 @@ std::shared_ptr<ProgramNode> Parser::parse()
|
||||
int Parser::advance()
|
||||
{
|
||||
++index;
|
||||
if (index < (ssize_t)tokens.size())
|
||||
if (index < tokens.size())
|
||||
{
|
||||
current_token = &tokens[index];
|
||||
}
|
||||
@ -136,7 +136,7 @@ Result<TopLevelNode> Parser::function()
|
||||
{
|
||||
proto.returnType = m_type_map.at(current_token->string_value.value());
|
||||
}
|
||||
catch (const std::out_of_range&)
|
||||
catch (std::out_of_range)
|
||||
{
|
||||
return Err<TopLevelNode>("Expected type name", current_token);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ class Parser
|
||||
private:
|
||||
Parser(const TokenStream& tokens);
|
||||
TokenStream tokens;
|
||||
ssize_t index = -1;
|
||||
int index = -1;
|
||||
int advance();
|
||||
Token* current_token;
|
||||
|
||||
|
@ -35,10 +35,10 @@ template<typename T> class Result
|
||||
bool m_is_error;
|
||||
std::string m_error;
|
||||
|
||||
Result(T* result, Token* token) : m_token(token), m_result(result), m_is_error(false)
|
||||
Result(T* result, Token* token) : m_result(result), m_token(token), m_is_error(false)
|
||||
{
|
||||
}
|
||||
Result(std::string&& error, Token* token) : m_token(token), m_is_error(true), m_error(error)
|
||||
Result(std::string&& error, Token* token) : m_error(error), m_token(token), m_is_error(true)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -1,22 +1,6 @@
|
||||
#include "Token.h"
|
||||
#include "utils.h"
|
||||
|
||||
Token::Token(const Token& other) : type(other.type), location(other.location), m_line_text(other.m_line_text)
|
||||
{
|
||||
if (other.int_value.has_value())
|
||||
{
|
||||
int_value = other.int_value.value();
|
||||
}
|
||||
else if (other.float_value.has_value())
|
||||
{
|
||||
float_value = other.float_value.value();
|
||||
}
|
||||
else if (other.string_value.has_value())
|
||||
{
|
||||
string_value = other.string_value.value();
|
||||
}
|
||||
}
|
||||
|
||||
Token::Token(TokenType type) : type(type), location(0, 0, "")
|
||||
{
|
||||
}
|
||||
@ -25,7 +9,7 @@ Token::Token(TokenType type, const Location& location) : type(type), location(lo
|
||||
{
|
||||
}
|
||||
|
||||
Token::Token(TokenType type, std::string value) : type(type), string_value(std::move(value)), location(0, 0, "")
|
||||
Token::Token(TokenType type, std::string value) : type(type), location(0, 0, ""), string_value(std::move(value))
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,34 +45,17 @@ Token Token::copy_with_new_type(const TokenType& type) const
|
||||
result.string_value = string_value.value();
|
||||
}
|
||||
|
||||
return result;
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
Token Token::make_with_line(const Token& origin, const std::string& line_text)
|
||||
{
|
||||
Token result = origin.copy_with_new_type(origin.type);
|
||||
|
||||
result.m_line_text = line_text;
|
||||
|
||||
return result;
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void Token::operator=(const Token& other)
|
||||
{
|
||||
type = other.type;
|
||||
location = other.location;
|
||||
m_line_text = other.m_line_text;
|
||||
|
||||
if (other.int_value.has_value())
|
||||
{
|
||||
int_value = other.int_value.value();
|
||||
}
|
||||
else if (other.float_value.has_value())
|
||||
{
|
||||
float_value = other.float_value.value();
|
||||
}
|
||||
else if (other.string_value.has_value())
|
||||
{
|
||||
string_value = other.string_value.value();
|
||||
}
|
||||
*this = other.copy_with_new_type(other.type);
|
||||
}
|
||||
|
@ -56,8 +56,6 @@ struct Token
|
||||
|
||||
Location location;
|
||||
|
||||
Token(const Token& other);
|
||||
|
||||
Token(TokenType type);
|
||||
|
||||
Token(TokenType type, const Location& location);
|
||||
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "",
|
||||
"stderr": "\u001b[1;1mtests/body-invalid-expr.sp:2:8: \u001b[31;49merror: \u001b[0;0mInvalid syntax\n2 0 5 +\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/body-invalid-expr.sp:2:7: \u001b[31;49merror: \u001b[0;0mInvalid syntax\n2 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "",
|
||||
"stderr": "\u001b[1;1mtests/body-not-math-expr.sp:2:5: \u001b[31;49merror: \u001b[0;0mexpected a number\n2 syscall1(60, 1); // sys_exit(1)\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/body-not-math-expr.sp:2:5: \u001b[31;49merror: \u001b[0;0mexpected a number\n2 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "",
|
||||
"stderr": "\u001b[1;1mtests/empty-let.sp:1:5: \u001b[31;49merror: \u001b[0;0mExpected @\n1 let;\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/empty-let.sp:1:4: \u001b[31;49merror: \u001b[0;0mExpected @\n1 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "",
|
||||
"stderr": "\u001b[1;1mtests/function-no-in.sp:1:20: \u001b[31;49merror: \u001b[0;0mExpected 'in' or semicolon\n1 let @main : i32 {\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/function-no-in.sp:1:17: \u001b[31;49merror: \u001b[0;0mExpected 'in' or semicolon\n1 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "",
|
||||
"stderr": "\u001b[1;1mtests/invalid-type.sp:1:15: \u001b[31;49merror: \u001b[0;0mExpected type name\n1 let @main : u56 in {\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/invalid-type.sp:1:13: \u001b[31;49merror: \u001b[0;0mExpected type name\n1 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "\u001b[1;1mtests/lex-multiple-periods.sp:2:9: \u001b[33;49mwarning: \u001b[0;0mfloats can only have one dot\n2 3.45.6\n \u001b[33;49m^\u001b[0;0m\n",
|
||||
"stderr": "\u001b[1;1mtests/lex-multiple-periods.sp:2:10: \u001b[31;49merror: \u001b[0;0mInvalid syntax\n2 3.45.6\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/lex-multiple-periods.sp:2:9: \u001b[31;49merror: \u001b[0;0mInvalid syntax\n2 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "",
|
||||
"stderr": "\u001b[1;1mtests/lex-unfinished-string.sp:3:0: \u001b[31;49merror: \u001b[0;0mexpected end of string but got newline\n3 'This is a test\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/lex-unfinished-string.sp:2:19: \u001b[31;49merror: \u001b[0;0mexpected end of string but got newline\n2 'This is a test\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "",
|
||||
"stderr": "\u001b[1;1mtests/top-level-math.sp:1:1: \u001b[31;49merror: \u001b[0;0mExpected let\n1 4 + 5 - 6\n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/top-level-math.sp:1:1: \u001b[31;49merror: \u001b[0;0mExpected let\n1 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
"flags": [],
|
||||
"exit-code": 1,
|
||||
"stdout": "",
|
||||
"stderr": "\u001b[1;1mtests/unended-function.sp:1:12: \u001b[31;49merror: \u001b[0;0mExpected 'in', colon or semicolon\n1 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
"stderr": "\u001b[1;1mtests/unended-function.sp:1:11: \u001b[31;49merror: \u001b[0;0mExpected 'in', colon or semicolon\n1 \n \u001b[31;49m^\u001b[0;0m\n"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user