forked from PuqiAR/Fig-TreeWalker
Compare commits
1 Commits
v0.3.9-alp
...
v0.4.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e3f17711f |
@@ -100,6 +100,8 @@ namespace Fig::Ast
|
||||
struct AstAddressInfo
|
||||
{
|
||||
size_t line, column;
|
||||
std::shared_ptr<FString> sourcePath;
|
||||
std::shared_ptr<std::vector<FString>> sourceLines;
|
||||
};
|
||||
|
||||
class _AstBase
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
#define __FCORE_VERSION "0.3.9-alpha"
|
||||
#define __FCORE_VERSION "0.4.0-alpha"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define __FCORE_PLATFORM "Windows"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <format>
|
||||
#include <source_location>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
@@ -16,8 +17,10 @@ namespace Fig
|
||||
explicit AddressableError(FString _msg,
|
||||
size_t _line,
|
||||
size_t _column,
|
||||
FString _sourcePath,
|
||||
std::vector<FString> _sourceLines,
|
||||
std::source_location loc = std::source_location::current()) :
|
||||
src_loc(loc), line(_line), column(_column)
|
||||
src_loc(loc), line(_line), column(_column), sourcePath(std::move(_sourcePath)), sourceLines(std::move(_sourceLines))
|
||||
{
|
||||
message = _msg;
|
||||
}
|
||||
@@ -33,9 +36,11 @@ namespace Fig
|
||||
}
|
||||
std::source_location src_loc;
|
||||
|
||||
size_t getLine() const { return line; }
|
||||
size_t getColumn() const { return column; }
|
||||
virtual size_t getLine() const { return line; }
|
||||
virtual size_t getColumn() const { return column; }
|
||||
FString getMessage() const { return message; }
|
||||
FString getSourcePath() const { return sourcePath; }
|
||||
std::vector<FString> getSourceLines() const { return sourceLines; }
|
||||
|
||||
virtual FString getErrorType() const
|
||||
{
|
||||
@@ -45,6 +50,9 @@ namespace Fig
|
||||
protected:
|
||||
size_t line, column;
|
||||
FString message;
|
||||
|
||||
FString sourcePath;
|
||||
std::vector<FString> sourceLines;
|
||||
};
|
||||
|
||||
class UnaddressableError : public std::exception
|
||||
@@ -84,14 +92,6 @@ namespace Fig
|
||||
public:
|
||||
using AddressableError::AddressableError;
|
||||
|
||||
explicit SyntaxError(FString _msg,
|
||||
size_t _line,
|
||||
size_t _column,
|
||||
std::source_location loc = std::source_location::current()) :
|
||||
AddressableError(_msg, _line, _column, loc)
|
||||
{
|
||||
}
|
||||
|
||||
virtual FString toString() const override
|
||||
{
|
||||
std::string msg = std::format("[SyntaxError] {} in [{}] {}", this->message.toBasicString(), this->src_loc.file_name(), this->src_loc.function_name());
|
||||
|
||||
@@ -98,8 +98,11 @@ namespace Fig
|
||||
}
|
||||
|
||||
|
||||
inline void logAddressableError(const AddressableError &err, FString fileName, std::vector<FString> sourceLines)
|
||||
inline void logAddressableError(const AddressableError &err)
|
||||
{
|
||||
const FString &fileName = err.getSourcePath();
|
||||
const std::vector<FString> &sourceLines = err.getSourceLines();
|
||||
|
||||
std::print("\n");
|
||||
namespace TC = TerminalColors;
|
||||
coloredPrint(TC::LightWhite, "An error occurred! ");
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifndef SourceInfo
|
||||
#define SourceInfo(ptr) (ptr->sourcePath), (ptr->sourceLines)
|
||||
#endif
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
|
||||
@@ -210,11 +214,10 @@ namespace Fig
|
||||
return evalIndexExpr(ie, ctx);
|
||||
}
|
||||
default: {
|
||||
// throw EvaluatorError(
|
||||
// u8"TypeError",
|
||||
// std::format("Expression '{}' doesn't refer to a lvalue", exp->typeName().toBasicString()),
|
||||
// exp);
|
||||
|
||||
throw EvaluatorError(
|
||||
u8"TypeError",
|
||||
std::format("Expression '{}' doesn't refer to a lvalue", exp->typeName().toBasicString()),
|
||||
exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,19 +337,15 @@ namespace Fig
|
||||
而 R 类型为 StructType (builtins.hpp) 中注册
|
||||
拿到 R 的 StructType, 其中的 type 为 String
|
||||
*/
|
||||
if (lhs->getTypeInfo() == type)
|
||||
{
|
||||
return Object::getTrueInstance();
|
||||
}
|
||||
if (lhs->getTypeInfo() == type) { return Object::getTrueInstance(); }
|
||||
return Object::getFalseInstance();
|
||||
}
|
||||
|
||||
throw EvaluatorError(
|
||||
u8"TypeError",
|
||||
std::format("Unsupported operator `is` for '{}' && '{}'",
|
||||
lhsType.toString().toBasicString(),
|
||||
rhsType.toString().toBasicString()),
|
||||
bin->lexp);
|
||||
throw EvaluatorError(u8"TypeError",
|
||||
std::format("Unsupported operator `is` for '{}' && '{}'",
|
||||
lhsType.toString().toBasicString(),
|
||||
rhsType.toString().toBasicString()),
|
||||
bin->lexp);
|
||||
}
|
||||
|
||||
case Operator::BitAnd: {
|
||||
@@ -1017,11 +1016,8 @@ namespace Fig
|
||||
return std::make_shared<Object>(std::move(map));
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw RuntimeError(FString(
|
||||
std::format("err type of expr: {}", magic_enum::enum_name(type))
|
||||
));
|
||||
default: {
|
||||
throw RuntimeError(FString(std::format("err type of expr: {}", magic_enum::enum_name(type))));
|
||||
}
|
||||
}
|
||||
return Object::getNullInstance(); // ignore warning
|
||||
@@ -1478,11 +1474,13 @@ namespace Fig
|
||||
case BreakSt: {
|
||||
if (!ctx->parent)
|
||||
{
|
||||
throw EvaluatorError(u8"BreakOutsideLoopError", u8"`break` statement outside loop", stmt);
|
||||
throw EvaluatorError(
|
||||
u8"BreakOutsideLoopError", u8"`break` statement outside loop", stmt);
|
||||
}
|
||||
if (!ctx->isInLoopContext())
|
||||
{
|
||||
throw EvaluatorError(u8"BreakOutsideLoopError", u8"`break` statement outside loop", stmt);
|
||||
throw EvaluatorError(
|
||||
u8"BreakOutsideLoopError", u8"`break` statement outside loop", stmt);
|
||||
}
|
||||
return StatementResult::breakFlow();
|
||||
}
|
||||
@@ -1490,11 +1488,13 @@ namespace Fig
|
||||
case ContinueSt: {
|
||||
if (!ctx->parent)
|
||||
{
|
||||
throw EvaluatorError(u8"ContinueOutsideLoopError", u8"`continue` statement outside loop", stmt);
|
||||
throw EvaluatorError(
|
||||
u8"ContinueOutsideLoopError", u8"`continue` statement outside loop", stmt);
|
||||
}
|
||||
if (!ctx->isInLoopContext())
|
||||
{
|
||||
throw EvaluatorError(u8"ContinueOutsideLoopError", u8"`continue` statement outside loop", stmt);
|
||||
throw EvaluatorError(
|
||||
u8"ContinueOutsideLoopError", u8"`continue` statement outside loop", stmt);
|
||||
}
|
||||
return StatementResult::continueFlow();
|
||||
}
|
||||
@@ -1620,28 +1620,30 @@ namespace Fig
|
||||
|
||||
ContextPtr Evaluator::loadModule(const std::filesystem::path &path)
|
||||
{
|
||||
FString modSourcePath(path.string());
|
||||
std::ifstream file(path);
|
||||
assert(file.is_open());
|
||||
|
||||
std::string source((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
file.close();
|
||||
|
||||
Lexer lexer((FString(source)));
|
||||
Parser parser(lexer);
|
||||
std::vector<Ast::AstBase> asts;
|
||||
std::vector<FString> modSourceLines = Utils::splitSource(FString(source));
|
||||
|
||||
std::vector<FString> sourceLines = Utils::splitSource(FString(source));
|
||||
Lexer lexer((FString(source)), modSourcePath, modSourceLines);
|
||||
Parser parser(lexer, modSourcePath, modSourceLines);
|
||||
std::vector<Ast::AstBase> asts;
|
||||
|
||||
asts = parser.parseAll();
|
||||
|
||||
Evaluator evaluator;
|
||||
evaluator.SetSourcePath(FString(path.string()));
|
||||
evaluator.SetSourcePath(modSourcePath);
|
||||
evaluator.SetSourceLines(modSourceLines);
|
||||
|
||||
ContextPtr modctx = std::make_shared<Context>(FString(std::format("<Module at {}>", path.string())), nullptr);
|
||||
|
||||
evaluator.SetGlobalContext(modctx);
|
||||
evaluator.RegisterBuiltinsValue();
|
||||
evaluator.Run(asts);
|
||||
evaluator.Run(asts); // error upward pass-by, log outside, we have already keep info in evaluator error
|
||||
|
||||
return evaluator.global;
|
||||
}
|
||||
@@ -1663,8 +1665,9 @@ namespace Fig
|
||||
|
||||
if (ctx->containsInThisScope(modName))
|
||||
{
|
||||
throw EvaluatorError(
|
||||
u8"RedeclarationError", std::format("{} has already been declared.", modName.toBasicString()), i);
|
||||
throw EvaluatorError(u8"RedeclarationError",
|
||||
std::format("{} has already been declared.", modName.toBasicString()),
|
||||
i);
|
||||
}
|
||||
ctx->def(
|
||||
modName, ValueType::Module, AccessModifier::PublicConst, std::make_shared<Object>(Module(modName, modCtx)));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Ast/Statements/ImplementSt.hpp"
|
||||
#include "Ast/Statements/InterfaceDefSt.hpp"
|
||||
#include "Value/Type.hpp"
|
||||
#include <Ast/Statements/ImplementSt.hpp>
|
||||
#include <Ast/Statements/InterfaceDefSt.hpp>
|
||||
#include <Value/Type.hpp>
|
||||
#include <Ast/ast.hpp>
|
||||
|
||||
#include <Context/context.hpp>
|
||||
@@ -63,12 +63,18 @@ namespace Fig
|
||||
|
||||
public:
|
||||
FString sourcePath;
|
||||
std::vector<FString> sourceLines;
|
||||
|
||||
void SetSourcePath(const FString &sp)
|
||||
{
|
||||
sourcePath = sp;
|
||||
}
|
||||
|
||||
void SetSourceLines(const std::vector<FString> &sl)
|
||||
{
|
||||
sourceLines = sl;
|
||||
}
|
||||
|
||||
void SetGlobalContext(ContextPtr ctx)
|
||||
{
|
||||
assert(ctx != nullptr);
|
||||
|
||||
@@ -10,7 +10,10 @@ namespace Fig
|
||||
public:
|
||||
FString typeName;
|
||||
using AddressableError::AddressableError;
|
||||
EvaluatorError(FString _typeName, FString msg, Ast::AstBase ast, std::source_location loc = std::source_location::current())
|
||||
EvaluatorError(FString _typeName,
|
||||
FString msg,
|
||||
Ast::AstBase ast,
|
||||
std::source_location loc = std::source_location::current())
|
||||
{
|
||||
message = msg;
|
||||
line = ast->getAAI().line;
|
||||
@@ -20,8 +23,13 @@ namespace Fig
|
||||
|
||||
typeName = std::move(_typeName);
|
||||
|
||||
sourcePath = *ast->getAAI().sourcePath;
|
||||
sourceLines = *ast->getAAI().sourceLines;
|
||||
}
|
||||
EvaluatorError(FString _typeName, std::string_view msg, Ast::AstBase ast, std::source_location loc = std::source_location::current())
|
||||
EvaluatorError(FString _typeName,
|
||||
std::string_view msg,
|
||||
Ast::AstBase ast,
|
||||
std::source_location loc = std::source_location::current())
|
||||
{
|
||||
message = FString::fromBasicString(std::string(msg.data()));
|
||||
line = ast->getAAI().line;
|
||||
@@ -30,13 +38,11 @@ namespace Fig
|
||||
src_loc = std::move(loc);
|
||||
|
||||
typeName = std::move(_typeName);
|
||||
|
||||
sourcePath = *ast->getAAI().sourcePath;
|
||||
sourceLines = *ast->getAAI().sourceLines;
|
||||
}
|
||||
|
||||
virtual FString getErrorType() const override
|
||||
{
|
||||
return typeName;
|
||||
}
|
||||
|
||||
|
||||
virtual FString getErrorType() const override { return typeName; }
|
||||
};
|
||||
};
|
||||
}; // namespace Fig
|
||||
@@ -89,7 +89,9 @@ int main(int argc, char **argv)
|
||||
std::string source((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
file.close();
|
||||
|
||||
Fig::Lexer lexer((Fig::FString(source)));
|
||||
std::vector<FString> sourceLines = Fig::Utils::splitSource(Fig::FString(source));
|
||||
|
||||
Fig::Lexer lexer((Fig::FString(source)), sourcePath, sourceLines);
|
||||
|
||||
// Token tok;
|
||||
// while ((tok = lexer.nextToken()).getType() != TokenType::EndOfFile)
|
||||
@@ -97,11 +99,9 @@ int main(int argc, char **argv)
|
||||
// std::println("{}", tok.toString().toBasicString());
|
||||
// }
|
||||
|
||||
Fig::Parser parser(lexer);
|
||||
Fig::Parser parser(lexer, sourcePath, sourceLines);
|
||||
std::vector<Fig::Ast::AstBase> asts;
|
||||
|
||||
std::vector<FString> sourceLines = Fig::Utils::splitSource(Fig::FString(source));
|
||||
|
||||
try
|
||||
{
|
||||
asts = parser.parseAll();
|
||||
@@ -109,7 +109,7 @@ int main(int argc, char **argv)
|
||||
catch (const Fig::AddressableError &e)
|
||||
{
|
||||
addressableErrorCount++;
|
||||
ErrorLog::logAddressableError(e, sourcePath, sourceLines);
|
||||
ErrorLog::logAddressableError(e);
|
||||
return 1;
|
||||
}
|
||||
catch (const Fig::UnaddressableError &e)
|
||||
@@ -134,6 +134,7 @@ int main(int argc, char **argv)
|
||||
Fig::Evaluator evaluator;
|
||||
|
||||
evaluator.SetSourcePath(sourcePath);
|
||||
evaluator.SetSourceLines(sourceLines);
|
||||
evaluator.CreateGlobalContext();
|
||||
evaluator.RegisterBuiltinsValue();
|
||||
|
||||
@@ -144,7 +145,7 @@ int main(int argc, char **argv)
|
||||
catch (const Fig::AddressableError &e)
|
||||
{
|
||||
addressableErrorCount++;
|
||||
ErrorLog::logAddressableError(e, sourcePath, sourceLines);
|
||||
ErrorLog::logAddressableError(e);
|
||||
evaluator.printStackTrace();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include <iostream> // debug
|
||||
#endif
|
||||
|
||||
#ifndef SourceInfo
|
||||
#define SourceInfo(ptr) (ptr->sourcePath), (ptr->sourceLines)
|
||||
#endif
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
|
||||
@@ -163,7 +167,7 @@ namespace Fig
|
||||
{
|
||||
if (it.isEnd())
|
||||
{
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, it.column());
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, it.column(), SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
next();
|
||||
@@ -200,12 +204,11 @@ namespace Fig
|
||||
}
|
||||
else
|
||||
{
|
||||
error = SyntaxError(FString(
|
||||
std::format(
|
||||
"Unsupported escape character: {}",
|
||||
FString(ec.getString()).toBasicString())),
|
||||
error = SyntaxError(FString(std::format("Unsupported escape character: {}",
|
||||
FString(ec.getString()).toBasicString())),
|
||||
this->line,
|
||||
it.column());
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
}
|
||||
@@ -217,7 +220,7 @@ namespace Fig
|
||||
}
|
||||
if (unterminated)
|
||||
{
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, str_start_col);
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, str_start_col, SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
return Token(str, TokenType::LiteralString);
|
||||
@@ -244,7 +247,7 @@ namespace Fig
|
||||
}
|
||||
if (unterminated)
|
||||
{
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, str_start_col);
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, str_start_col, SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
return Token(str, TokenType::LiteralString);
|
||||
@@ -275,7 +278,7 @@ namespace Fig
|
||||
{
|
||||
if (it.isEnd())
|
||||
{
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, it.column());
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, it.column(), SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
next();
|
||||
@@ -317,12 +320,11 @@ namespace Fig
|
||||
}
|
||||
else
|
||||
{
|
||||
error = SyntaxError(FString(
|
||||
std::format(
|
||||
"Unsupported escape character: {}",
|
||||
FString(ec.getString()).toBasicString())),
|
||||
error = SyntaxError(FString(std::format("Unsupported escape character: {}",
|
||||
FString(ec.getString()).toBasicString())),
|
||||
this->line,
|
||||
it.column());
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
}
|
||||
@@ -334,7 +336,7 @@ namespace Fig
|
||||
}
|
||||
if (unterminated)
|
||||
{
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, str_start_col);
|
||||
error = SyntaxError(u8"Unterminated FString", this->line, str_start_col, SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
return Token(str, TokenType::LiteralString);
|
||||
@@ -378,8 +380,10 @@ namespace Fig
|
||||
|
||||
if (numStr.ends_with(U'e'))
|
||||
{
|
||||
error = SyntaxError(
|
||||
FString(std::format("Illegal number literal: {}", numStr.toBasicString())), this->line, it.column());
|
||||
error = SyntaxError(FString(std::format("Illegal number literal: {}", numStr.toBasicString())),
|
||||
this->line,
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
|
||||
@@ -395,8 +399,10 @@ namespace Fig
|
||||
|
||||
if (!hasDigit)
|
||||
{
|
||||
error = SyntaxError(
|
||||
FString(std::format("Illegal number literal: {}", numStr.toBasicString())), this->line, it.column());
|
||||
error = SyntaxError(FString(std::format("Illegal number literal: {}", numStr.toBasicString())),
|
||||
this->line,
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
|
||||
@@ -407,14 +413,16 @@ namespace Fig
|
||||
{
|
||||
error = SyntaxError(FString(std::format("Illegal number literal: {}", numStr.toBasicString())),
|
||||
this->line,
|
||||
it.column());
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
if (ePos + 1 >= numStr.length())
|
||||
{
|
||||
error = SyntaxError(FString(std::format("Illegal number literal: {}", numStr.toBasicString())),
|
||||
this->line,
|
||||
it.column());
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
bool hasDigitAfterE = false;
|
||||
@@ -427,7 +435,8 @@ namespace Fig
|
||||
{
|
||||
error = SyntaxError(FString(std::format("Illegal number literal: {}", numStr.toBasicString())),
|
||||
this->line,
|
||||
it.column());
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
continue;
|
||||
@@ -438,7 +447,8 @@ namespace Fig
|
||||
{
|
||||
error = SyntaxError(FString(std::format("Illegal number literal: {}", numStr.toBasicString())),
|
||||
this->line,
|
||||
it.column());
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
}
|
||||
@@ -447,7 +457,8 @@ namespace Fig
|
||||
{
|
||||
error = SyntaxError(FString(std::format("Illegal number literal: {}", numStr.toBasicString())),
|
||||
this->line,
|
||||
it.column());
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
return IllegalTok;
|
||||
}
|
||||
}
|
||||
@@ -472,9 +483,10 @@ namespace Fig
|
||||
|
||||
if (!startsWith(sym))
|
||||
{
|
||||
error = SyntaxError(
|
||||
FString(std::format("No such operator: {}", sym.toBasicString())),
|
||||
this->line, it.column());
|
||||
error = SyntaxError(FString(std::format("No such operator: {}", sym.toBasicString())),
|
||||
this->line,
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
next();
|
||||
return IllegalTok;
|
||||
}
|
||||
@@ -500,9 +512,10 @@ namespace Fig
|
||||
|
||||
if (!symbol_map.contains(sym))
|
||||
{
|
||||
error = SyntaxError(
|
||||
FString(std::format("No such operator: {}", sym.toBasicString())),
|
||||
this->line, it.column());
|
||||
error = SyntaxError(FString(std::format("No such operator: {}", sym.toBasicString())),
|
||||
this->line,
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
next();
|
||||
return IllegalTok;
|
||||
}
|
||||
@@ -562,7 +575,8 @@ namespace Fig
|
||||
|
||||
if (!terminated)
|
||||
{
|
||||
error = SyntaxError(FString(u8"Unterminated multiline comment"), this->line, it.column());
|
||||
error =
|
||||
SyntaxError(FString(u8"Unterminated multiline comment"), this->line, it.column(), SourceInfo(this));
|
||||
next();
|
||||
return IllegalTok;
|
||||
}
|
||||
@@ -633,9 +647,11 @@ namespace Fig
|
||||
}
|
||||
else
|
||||
{
|
||||
error = SyntaxError(FString(
|
||||
std::format("Cannot tokenize char: '{}'", FString(ch.getString()).toBasicString())),
|
||||
this->line, it.column());
|
||||
error =
|
||||
SyntaxError(FString(std::format("Cannot tokenize char: '{}'", FString(ch.getString()).toBasicString())),
|
||||
this->line,
|
||||
it.column(),
|
||||
SourceInfo(this));
|
||||
if (hasNext())
|
||||
{
|
||||
next();
|
||||
|
||||
@@ -23,6 +23,9 @@ namespace Fig
|
||||
SyntaxError error;
|
||||
UTF8Iterator it;
|
||||
|
||||
FString sourcePath;
|
||||
std::vector<FString> sourceLines;
|
||||
|
||||
std::vector<Warning> warnings;
|
||||
|
||||
size_t last_line, last_column, column = 1;
|
||||
@@ -60,8 +63,8 @@ namespace Fig
|
||||
static const std::unordered_map<FString, TokenType> symbol_map;
|
||||
static const std::unordered_map<FString, TokenType> keyword_map;
|
||||
|
||||
inline Lexer(const FString &_source) :
|
||||
source(_source), it(source)
|
||||
inline Lexer(const FString &_source, const FString &_sourcePath, const std::vector<FString> &_sourceLines) :
|
||||
source(_source), it(source), sourcePath(_sourcePath), sourceLines(_sourceLines)
|
||||
{
|
||||
line = 1;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public struct Time
|
||||
const result := ns - time_ns;
|
||||
if result < 0
|
||||
{
|
||||
throw "time has reversed! 😢";
|
||||
throw "time has been reversed! 😢";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Fig
|
||||
// 逻辑
|
||||
{Ast::Operator::And, {5, 6}},
|
||||
{Ast::Operator::Or, {4, 5}},
|
||||
{Ast::Operator::Not, {30, 31}}, // 一元
|
||||
// {Ast::Operator::Not, {30, 31}}, // 一元
|
||||
|
||||
// 比较
|
||||
{Ast::Operator::Equal, {7, 8}},
|
||||
@@ -37,7 +37,7 @@ namespace Fig
|
||||
{Ast::Operator::BitAnd, {6, 7}},
|
||||
{Ast::Operator::BitOr, {4, 5}},
|
||||
{Ast::Operator::BitXor, {5, 6}},
|
||||
{Ast::Operator::BitNot, {30, 31}}, // 一元
|
||||
// {Ast::Operator::BitNot, {30, 31}}, // 一元
|
||||
{Ast::Operator::ShiftLeft, {15, 16}},
|
||||
{Ast::Operator::ShiftRight, {15, 16}},
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace Fig
|
||||
variaPara = pname;
|
||||
next(); // skip `...`
|
||||
if (!isThis(TokenType::RightParen))
|
||||
throw SyntaxError(
|
||||
throwAddressableError<SyntaxError>(
|
||||
u8"Expects right paren, variable parameter function can only have one parameter",
|
||||
currentAAI.line,
|
||||
currentAAI.column);
|
||||
@@ -433,7 +433,7 @@ namespace Fig
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SyntaxError(FString(u8"Invalid syntax"), currentAAI.line, currentAAI.column);
|
||||
throwAddressableError<SyntaxError>(FString(u8"Invalid syntax"), currentAAI.line, currentAAI.column);
|
||||
}
|
||||
}
|
||||
return makeAst<Ast::InterfaceDefAst>(interfaceName, methods, isPublic);
|
||||
@@ -480,7 +480,7 @@ namespace Fig
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SyntaxError(FString(u8"Invalid syntax"), currentAAI.line, currentAAI.column);
|
||||
throwAddressableError<SyntaxError>(FString(u8"Invalid syntax"), currentAAI.line, currentAAI.column);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,7 +556,8 @@ namespace Fig
|
||||
{
|
||||
if (finallyBlock != nullptr)
|
||||
{
|
||||
throw SyntaxError(u8"Duplicate try finally-block", currentAAI.line, currentAAI.column);
|
||||
throwAddressableError<SyntaxError>(
|
||||
u8"Duplicate try finally-block", currentAAI.line, currentAAI.column);
|
||||
}
|
||||
next(); // consume `finally`
|
||||
expect(TokenType::LeftBrace);
|
||||
@@ -678,11 +679,7 @@ namespace Fig
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SyntaxError(
|
||||
u8"invalid syntax",
|
||||
currentAAI.line,
|
||||
currentAAI.column
|
||||
);
|
||||
throwAddressableError<SyntaxError>(u8"invalid syntax", currentAAI.line, currentAAI.column);
|
||||
}
|
||||
return stmt;
|
||||
}
|
||||
@@ -1208,11 +1205,11 @@ namespace Fig
|
||||
if (!isTokenOp(tok)) break;
|
||||
|
||||
op = Ast::TokenToOp.at(tok.getType());
|
||||
Precedence lbp = getLeftBindingPower(op);
|
||||
auto [lbp, rbp] = getBindingPower(op);
|
||||
if (bp >= lbp) break;
|
||||
|
||||
next(); // consume op
|
||||
lhs = makeAst<Ast::BinaryExprAst>(lhs, op, parseExpression(bp, stop, stop2));
|
||||
lhs = makeAst<Ast::BinaryExprAst>(lhs, op, parseExpression(rbp, stop, stop2));
|
||||
}
|
||||
|
||||
return lhs;
|
||||
@@ -1232,10 +1229,8 @@ namespace Fig
|
||||
auto stmt = __parseStatement();
|
||||
if (!output.empty() && stmt->getType() == Ast::AstType::PackageSt)
|
||||
{
|
||||
throw SyntaxError(
|
||||
u8"Package must be at the beginning of the file",
|
||||
currentAAI.line,
|
||||
currentAAI.column);
|
||||
throwAddressableError<SyntaxError>(
|
||||
u8"Package must be at the beginning of the file", currentAAI.line, currentAAI.column);
|
||||
}
|
||||
pushNode(stmt);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Core/fig_string.hpp>
|
||||
#include <Error/error.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <print>
|
||||
#include <source_location>
|
||||
#include <unordered_map>
|
||||
@@ -22,6 +23,9 @@ namespace Fig
|
||||
std::vector<Ast::AstBase> output;
|
||||
std::vector<Token> previousTokens;
|
||||
|
||||
std::shared_ptr<FString> sourcePathPtr;
|
||||
std::shared_ptr<std::vector<FString>> sourceLinesPtr;
|
||||
|
||||
size_t tokenPruduced = 0;
|
||||
size_t currentTokenIndex = 0;
|
||||
|
||||
@@ -72,7 +76,11 @@ namespace Fig
|
||||
static const std::unordered_map<Ast::Operator, std::pair<Precedence, Precedence>> opPrecedence;
|
||||
static const std::unordered_map<Ast::Operator, Precedence> unaryOpPrecedence;
|
||||
|
||||
Parser(const Lexer &_lexer) : lexer(_lexer) {}
|
||||
Parser(const Lexer &_lexer, FString _sourcePath, std::vector<FString> _sourceLines) : lexer(_lexer)
|
||||
{
|
||||
sourcePathPtr = std::make_shared<FString>(_sourcePath);
|
||||
sourceLinesPtr = std::make_shared<std::vector<FString>>(_sourceLines);
|
||||
}
|
||||
|
||||
AddressableError *getError() const { return error.get(); }
|
||||
|
||||
@@ -83,7 +91,7 @@ namespace Fig
|
||||
std::source_location loc = std::source_location::current())
|
||||
{
|
||||
static_assert(std::is_base_of_v<AddressableError, _ErrT>, "_ErrT must derive from AddressableError");
|
||||
_ErrT spError(msg, line, column, loc);
|
||||
_ErrT spError(msg, line, column, *sourcePathPtr, *sourceLinesPtr, loc);
|
||||
error = std::make_unique<_ErrT>(spError);
|
||||
throw spError;
|
||||
}
|
||||
@@ -92,7 +100,7 @@ namespace Fig
|
||||
{
|
||||
static_assert(std::is_base_of_v<AddressableError, _ErrT>, "_ErrT must derive from AddressableError");
|
||||
// line, column provide by `currentAAI`
|
||||
_ErrT spError(msg, currentAAI.line, currentAAI.column, loc);
|
||||
_ErrT spError(msg, currentAAI.line, currentAAI.column, *sourcePathPtr, *sourceLinesPtr, loc);
|
||||
error = std::make_unique<_ErrT>(spError);
|
||||
throw spError;
|
||||
}
|
||||
@@ -135,7 +143,10 @@ namespace Fig
|
||||
CTI也需要显示转换,否则转换完的pruduced又会被转回去,变为 int64_t max
|
||||
*/
|
||||
currentTokenIndex++;
|
||||
setCurrentAAI(Ast::AstAddressInfo{.line = currentToken().line, .column = currentToken().column});
|
||||
setCurrentAAI(Ast::AstAddressInfo{.line = currentToken().line,
|
||||
.column = currentToken().column,
|
||||
.sourcePath = sourcePathPtr,
|
||||
.sourceLines = sourceLinesPtr});
|
||||
return;
|
||||
}
|
||||
if (isEOF()) return;
|
||||
@@ -143,7 +154,11 @@ namespace Fig
|
||||
tokenPruduced++;
|
||||
if (tok == IllegalTok) throw lexer.getError();
|
||||
currentTokenIndex = tokenPruduced - 1;
|
||||
setCurrentAAI(Ast::AstAddressInfo{.line = tok.line, .column = tok.column});
|
||||
setCurrentAAI(Ast::AstAddressInfo{.line = tok.line,
|
||||
.column = tok.column,
|
||||
.sourcePath = sourcePathPtr,
|
||||
.sourceLines = sourceLinesPtr});
|
||||
|
||||
previousTokens.push_back(tok);
|
||||
}
|
||||
inline const Token ¤tToken()
|
||||
@@ -298,9 +313,8 @@ namespace Fig
|
||||
Ast::ListExpr __parseListExpr(); // entry: current is `[`
|
||||
Ast::MapExpr __parseMapExpr(); // entry: current is `{`
|
||||
|
||||
Ast::InitExpr __parseInitExpr(
|
||||
Ast::Expression); // entry: current is `{`, ahead is struct type exp.
|
||||
Ast::Expression __parseTupleOrParenExpr(); // entry: current is `(`
|
||||
Ast::InitExpr __parseInitExpr(Ast::Expression); // entry: current is `{`, ahead is struct type exp.
|
||||
Ast::Expression __parseTupleOrParenExpr(); // entry: current is `(`
|
||||
|
||||
Ast::FunctionLiteralExpr __parseFunctionLiteralExpr(); // entry: current is Token::LParen after Token::Function
|
||||
|
||||
|
||||
Reference in New Issue
Block a user