Compare commits

..

No commits in common. "a0945e54b24ad8d052d6c58f1e20ae00b6c64b4a" and "dbd5627fe6029b827eff919b684abe2513edf033" have entirely different histories.

26 changed files with 48 additions and 101 deletions

View File

@ -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/tclap-1.2.5/include)
target_include_directories(sapphirec PUBLIC src/external) target_include_directories(sapphirec PUBLIC src/external)
target_precompile_headers(sapphirec PUBLIC src/sapphirepch.h) 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) llvm_map_components_to_libnames(llvm_libs all core support irreader x86asmparser x86codegen x86desc x86disassembler x86info x86targetmca aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils)

View File

@ -1,7 +1,7 @@
#include "BinaryOpNode.h" #include "BinaryOpNode.h"
BinaryOpNode::BinaryOpNode(std::shared_ptr<ExprNode> left, std::shared_ptr<ExprNode> right) BinaryOpNode::BinaryOpNode(std::shared_ptr<ExprNode> left, std::shared_ptr<ExprNode> right)
: ExprNode(), left(left), right(right) : left(left), right(right), ExprNode()
{ {
} }

View File

@ -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); llvm::Function* Function = module->getFunction(prototype.name);
if (!Function) if (!Function)

View File

@ -1,6 +1,6 @@
#include "ExprNode.h" #include "ExprNode.h"
ExprNode::ExprNode(std::shared_ptr<ExprNode> child) : ASTNode(), child(child) ExprNode::ExprNode(std::shared_ptr<ExprNode> child) : child(child), ASTNode()
{ {
} }

View File

@ -1,6 +1,6 @@
#include "StatementNode.h" #include "StatementNode.h"
StatementNode::StatementNode(std::shared_ptr<ExprNode> child) : ASTNode(), child(child) StatementNode::StatementNode(std::shared_ptr<ExprNode> child) : child(child), ASTNode()
{ {
} }

View File

@ -5,10 +5,7 @@
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.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 Syscall0Node::Syscall0Node(int syscall_number) : sys_num(syscall_number), ExprNode()
// 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)
{ {
} }
@ -17,7 +14,7 @@ Syscall0Node::~Syscall0Node()
} }
Syscall1Node::Syscall1Node(int syscall_number, std::shared_ptr<ASTNode> arg1) 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) 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, Syscall3Node::Syscall3Node(int syscall_number, std::shared_ptr<ASTNode> arg1, std::shared_ptr<ASTNode> arg2,
std::shared_ptr<ASTNode> arg3) 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, 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) 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, 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) 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()
{ {
} }

View File

@ -1,6 +1,6 @@
#include "UnaryOpNode.h" #include "UnaryOpNode.h"
UnaryOpNode::UnaryOpNode(std::shared_ptr<ExprNode> operand) : ExprNode(), operand(operand) UnaryOpNode::UnaryOpNode(std::shared_ptr<ExprNode> operand) : operand(operand), ExprNode()
{ {
} }

View File

@ -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) [[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); show_import_lines(loc, show_import_line, std::cerr);

View File

@ -7,7 +7,7 @@
#define IDENTIFIERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ_0123456789" #define IDENTIFIERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ_0123456789"
#define DIGITS "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() int Lexer::advance()
{ {
previous_location = Location{ location }; previous_location = location;
++index; ++index;
location.advance(); 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]; current_char = current_lexed_text[index];
location.pos_from_char(current_char); location.pos_from_char(current_char);
if (current_char == '\n') if (current_char == '\n')
@ -46,10 +46,10 @@ int Lexer::rewind()
std::string Lexer::recalculate_current_line(const std::string& text) std::string Lexer::recalculate_current_line(const std::string& text)
{ {
ssize_t idx = index; int idx = index;
std::string final_str; std::string final_str;
++idx; ++idx;
while (idx != (ssize_t)text.size() && text[idx] != '\n') while (idx != text.size() && text[idx] != '\n')
{ {
final_str += text[idx]; final_str += text[idx];
++idx; ++idx;
@ -106,7 +106,7 @@ TokenStream Lexer::lex(const std::string& text)
switch (current_char) switch (current_char)
{ {
case '/': case '/':
if (index + 1 != (ssize_t)current_lexed_text.size()) if (index + 1 != current_lexed_text.size())
{ {
if (current_lexed_text[index + 1] == '/') if (current_lexed_text[index + 1] == '/')
{ {
@ -172,7 +172,7 @@ TokenStream Lexer::lex(const std::string& text)
break; break;
case '\377': case '\377':
result.push_back(Token(TT_EOF, location)); result.push_back(Token(TT_EOF, location));
return result; return std::move(result);
default: default:
Error::throw_error(location, current_line_text, "unknown character"); 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)); result.push_back(Token(TT_EOF, location));
return result; return std::move(result);
} }
Token Lexer::create_identifier() Token Lexer::create_identifier()
@ -303,7 +303,7 @@ Token Lexer::create_string()
} }
if (current_char == '\\') 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"); Error::throw_error(location, current_line_text, "unfinished escape sequence");
} }

View File

@ -19,7 +19,7 @@ class Lexer
int advance(); int advance();
int rewind(); int rewind();
char current_char; char current_char;
ssize_t index; int index;
Lexer(const std::string& filename); Lexer(const std::string& filename);

View File

@ -30,19 +30,18 @@ void Location::pos_from_char(const char& character)
} }
} }
Location::Location(const Location& other) void Location::operator=(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))
{ {
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 Location::copy(const Location& other)
{ {
Location result(other.line, other.column, other.filename); Location result(other.line, other.column, other.filename);
result.parent = other.parent; result.parent = other.parent;
return result; return std::move(result);
} }

View File

@ -14,14 +14,6 @@ struct Location
/* Creates a Location with the given parameters. */ /* Creates a Location with the given parameters. */
Location(int line, int column, std::string filename); Location(int line, int column, std::string filename);
Location(Location&& other);
Location(const Location& other);
Location operator=(const Location& other)
{
return Location(other);
}
~Location(); ~Location();
/* Returns a string of the format FILE:LINE:COL. */ /* Returns a string of the format FILE:LINE:COL. */
@ -33,6 +25,8 @@ struct Location
/* Advance to the next line if provided a newline. */ /* Advance to the next line if provided a newline. */
void pos_from_char(const char& character); void pos_from_char(const char& character);
void operator=(const Location& other);
/* Returns a copy of the original Location. */ /* Returns a copy of the original Location. */
static Location copy(const Location& other); static Location copy(const Location& other);
}; };

View File

@ -37,7 +37,7 @@ std::shared_ptr<ProgramNode> Parser::parse()
int Parser::advance() int Parser::advance()
{ {
++index; ++index;
if (index < (ssize_t)tokens.size()) if (index < tokens.size())
{ {
current_token = &tokens[index]; current_token = &tokens[index];
} }
@ -136,7 +136,7 @@ Result<TopLevelNode> Parser::function()
{ {
proto.returnType = m_type_map.at(current_token->string_value.value()); 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); return Err<TopLevelNode>("Expected type name", current_token);
} }

View File

@ -14,7 +14,7 @@ class Parser
private: private:
Parser(const TokenStream& tokens); Parser(const TokenStream& tokens);
TokenStream tokens; TokenStream tokens;
ssize_t index = -1; int index = -1;
int advance(); int advance();
Token* current_token; Token* current_token;

View File

@ -35,10 +35,10 @@ template<typename T> class Result
bool m_is_error; bool m_is_error;
std::string m_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)
{ {
} }
}; };

View File

@ -1,22 +1,6 @@
#include "Token.h" #include "Token.h"
#include "utils.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, "") 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(); 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 Token::make_with_line(const Token& origin, const std::string& line_text)
{ {
Token result = origin.copy_with_new_type(origin.type); Token result = origin.copy_with_new_type(origin.type);
result.m_line_text = line_text; return std::move(result);
return result;
} }
void Token::operator=(const Token& other) void Token::operator=(const Token& other)
{ {
type = other.type; *this = other.copy_with_new_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();
}
} }

View File

@ -56,8 +56,6 @@ struct Token
Location location; Location location;
Token(const Token& other);
Token(TokenType type); Token(TokenType type);
Token(TokenType type, const Location& location); Token(TokenType type, const Location& location);

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "exit-code": 1,
"stdout": "", "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"
} }
} }

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "exit-code": 1,
"stdout": "", "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"
} }
} }

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "exit-code": 1,
"stdout": "", "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"
} }
} }

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "exit-code": 1,
"stdout": "", "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"
} }
} }

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "exit-code": 1,
"stdout": "", "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"
} }
} }

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "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", "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"
} }
} }

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "exit-code": 1,
"stdout": "", "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"
} }
} }

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "exit-code": 1,
"stdout": "", "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"
} }
} }

View File

@ -4,6 +4,6 @@
"flags": [], "flags": [],
"exit-code": 1, "exit-code": 1,
"stdout": "", "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"
} }
} }