这是一条 msg. ( 正文:error log修改。新增std.tester。parser precedence重写

This commit is contained in:
2026-02-01 20:01:59 +08:00
parent aea716ced2
commit 41bff72d44
6 changed files with 163 additions and 53 deletions

View File

@@ -110,21 +110,31 @@ namespace Fig
coloredPrint(TC::LightRed, ""); coloredPrint(TC::LightRed, "");
coloredPrint(TC::LightRed, std::format("{}: {}\n", err.getErrorType().toBasicString(), FString(err.getMessage()).toBasicString())); coloredPrint(TC::LightRed, std::format("{}: {}\n", err.getErrorType().toBasicString(), FString(err.getMessage()).toBasicString()));
coloredPrint(TC::White, std::format(" at {}:{} in file '{}'\n", err.getLine(), err.getColumn(), fileName.toBasicString())); coloredPrint(TC::White, std::format(" at {}:{} in file '{}'\n", err.getLine(), err.getColumn(), fileName.toBasicString()));
FString lineContent = ((int64_t(err.getLine()) - int64_t(1)) >= 0 ? sourceLines[err.getLine() - 1] : u8"<No Source>");
coloredPrint(TC::LightBlue, std::format(" {}\n", lineContent.toBasicString())); FString lineContent;
FString pointerLine; FString pointerLine;
for (size_t i = 1; i < err.getColumn(); ++i)
if (fileName != u8"<stdin>")
{ {
if (lineContent[i - 1] == U'\t') lineContent = ((int64_t(err.getLine()) - int64_t(1)) >= 0 ? sourceLines[err.getLine() - 1] : u8"<No Source>");
FString pointerLine;
for (size_t i = 1; i < err.getColumn(); ++i)
{ {
pointerLine += U'\t'; if (lineContent[i - 1] == U'\t') { pointerLine += U'\t'; }
} else
else {
{ pointerLine += U' ';
pointerLine += U' '; }
} }
pointerLine += U'^';
} }
pointerLine += U'^'; else
{
lineContent = fileName;
}
coloredPrint(TC::LightBlue, std::format(" {}\n", lineContent.toBasicString()));
coloredPrint(TC::LightGreen, std::format(" {}\n", pointerLine.toBasicString())); coloredPrint(TC::LightGreen, std::format(" {}\n", pointerLine.toBasicString()));
coloredPrint(TC::DarkGray, std::format("🔧 in function '{}' ({}:{})\n", err.src_loc.function_name(), err.src_loc.file_name(), err.src_loc.line())); coloredPrint(TC::DarkGray, std::format("🔧 in function '{}' ({}:{})\n", err.src_loc.function_name(), err.src_loc.file_name(), err.src_loc.line()));
} }

View File

@@ -429,7 +429,7 @@ namespace Fig
{ {
if (is<ValueType::NullClass>()) return FString(u8"null"); if (is<ValueType::NullClass>()) return FString(u8"null");
if (is<ValueType::IntClass>()) return FString(std::to_string(as<ValueType::IntClass>())); if (is<ValueType::IntClass>()) return FString(std::to_string(as<ValueType::IntClass>()));
if (is<ValueType::DoubleClass>()) return FString(std::format("{:g}", as<ValueType::DoubleClass>())); if (is<ValueType::DoubleClass>()) return FString(std::format("{}", as<ValueType::DoubleClass>()));
if (is<ValueType::StringClass>()) return FString(u8"\"" + as<ValueType::StringClass>() + u8"\""); if (is<ValueType::StringClass>()) return FString(u8"\"" + as<ValueType::StringClass>() + u8"\"");
if (is<ValueType::BoolClass>()) return as<ValueType::BoolClass>() ? FString(u8"true") : FString(u8"false"); if (is<ValueType::BoolClass>()) return as<ValueType::BoolClass>() ? FString(u8"true") : FString(u8"false");
if (is<Function>()) if (is<Function>())

View File

@@ -6,3 +6,4 @@
import io; // link std.io import io; // link std.io
import value; // link std.type import value; // link std.type
import math; // link std.math import math; // link std.math
import tester; // link std.tester

View File

@@ -0,0 +1,86 @@
/*
Official Module `std.tester`
Library/std/tester/tester.fig
Copyright © 2025 PuqiAR. All rights reserved.
*/
import std.time;
import std.io;
// import std.value;
// import std.math;
// import std.formater;
// const library_load_time := time.now();
// io.println("All std libraries loaded! Cost:", library_load_time.toSeconds(), "s\n");
public struct Test
{
public case: String;
public fn: Function;
public expect_result: Any;
public func Run()
{
const start := time.now();
const result := fn();
const end := time.now();
const duration := new time.Time{ end.since(start) };
if result != expect_result
{
io.println("❌ Test '" + case + "'" + " failed");
io.println(" expect", expect_result, ", got", result);
return 1;
}
else
{
io.println("✔ Test '" + case + "'" + " succeed");
io.println(" result:", result);
return 0;
}
}
}
public struct Tester
{
public tests: List = [];
public func AddTest(test: Test)
{
tests.push(test);
}
public func TestAll()
{
const numtests := tests.length();
var success := 0;
var fail := 0;
for var i := 0; i < numtests; i += 1
{
io.printf("({}/{})", i + 1, numtests);
var result := tests[i].Run();
if result == 0
{
success += 1;
}
else
{
fail += 1;
}
}
io.println();
io.println("=" * 100);
io.println("All tests executed");
io.printf(" ({}/{}) success tested!\n", success, numtests);
io.printf(" ({}/{}) failed!\n", fail, numtests);
}
}

View File

@@ -117,7 +117,9 @@ namespace Fig::Builtins
return std::make_shared<Object>(FString::fromBasicString(line)); return std::make_shared<Object>(FString::fromBasicString(line));
}}, }},
{u8"__fvalue_type", {u8"__fvalue_type",
[](const std::vector<ObjectPtr> &args) -> ObjectPtr { return std::make_shared<Object>(); }}, [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
return std::make_shared<Object>(args[0]->getTypeInfo().toString());
}},
{u8"__fvalue_int_parse", {u8"__fvalue_int_parse",
[](const std::vector<ObjectPtr> &args) -> ObjectPtr { [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
FString str = args[0]->as<ValueType::StringClass>(); FString str = args[0]->as<ValueType::StringClass>();

View File

@@ -9,59 +9,70 @@
namespace Fig namespace Fig
{ {
// Operator : pair<LeftBindingPower, RightBindingPower> // Operator : pair<LeftBindingPower, RightBindingPower>
const std::unordered_map<Ast::Operator, std::pair<Parser::Precedence, Parser::Precedence>> Parser::opPrecedence = { const std::unordered_map<Ast::Operator, std::pair<Parser::Precedence, Parser::Precedence>> Parser::opPrecedence = {
// 算术 // 赋值类 - 右结合
{Ast::Operator::Add, {10, 11}}, {Ast::Operator::Assign, {20, 10}},
{Ast::Operator::Subtract, {10, 11}}, {Ast::Operator::PlusAssign, {20, 10}},
{Ast::Operator::Multiply, {20, 21}}, {Ast::Operator::MinusAssign, {20, 10}},
{Ast::Operator::Divide, {20, 21}}, {Ast::Operator::SlashAssign, {20, 10}},
{Ast::Operator::Modulo, {20, 21}}, {Ast::Operator::AsteriskAssign, {20, 10}},
{Ast::Operator::Power, {30, 29}}, {Ast::Operator::PercentAssign, {20, 10}},
{Ast::Operator::CaretAssign, {20, 10}},
// 逻辑 // 三元条件 - 特殊处理,通常是右结合
{Ast::Operator::And, {5, 6}}, {Ast::Operator::TernaryCond, {30, 20}},
{Ast::Operator::Or, {4, 5}},
// {Ast::Operator::Not, {30, 31}}, // 一元
// 比较 // 逻辑或
{Ast::Operator::Equal, {7, 8}}, {Ast::Operator::Or, {40, 41}}, // leftBP < rightBP左结合
{Ast::Operator::NotEqual, {7, 8}},
{Ast::Operator::Less, {8, 9}},
{Ast::Operator::LessEqual, {8, 9}},
{Ast::Operator::Greater, {8, 9}},
{Ast::Operator::GreaterEqual, {8, 9}},
{Ast::Operator::Is, {8, 9}},
// 位运算 // 逻辑与
{Ast::Operator::BitAnd, {6, 7}}, {Ast::Operator::And, {50, 51}}, // 比 Or 高
{Ast::Operator::BitOr, {4, 5}},
{Ast::Operator::BitXor, {5, 6}},
// {Ast::Operator::BitNot, {30, 31}}, // 一元
{Ast::Operator::ShiftLeft, {15, 16}},
{Ast::Operator::ShiftRight, {15, 16}},
{Ast::Operator::Assign, {2, 1}}, // 右结合 // 位或
{Ast::Operator::PlusAssign, {2, 1}}, {Ast::Operator::BitOr, {60, 61}},
{Ast::Operator::MinusAssign, {2, 1}},
{Ast::Operator::SlashAssign, {2, 1}},
{Ast::Operator::AsteriskAssign, {2, 1}},
{Ast::Operator::PercentAssign, {2, 1}},
{Ast::Operator::CaretAssign, {2, 1}},
// 海象运算符 // 位异或
// {Ast::Operator::Walrus, {2, 1}}, // 右结合 {Ast::Operator::BitXor, {70, 71}},
// // 点运算符 // 位与
// {Ast::Operator::Dot, {40, 41}}, {Ast::Operator::BitAnd, {80, 81}},
{Ast::Operator::TernaryCond, {3, 2}},
// 相等比较
{Ast::Operator::Equal, {90, 91}},
{Ast::Operator::NotEqual, {90, 91}},
// 关系比较
{Ast::Operator::Less, {100, 101}},
{Ast::Operator::LessEqual, {100, 101}},
{Ast::Operator::Greater, {100, 101}},
{Ast::Operator::GreaterEqual, {100, 101}},
{Ast::Operator::Is, {100, 101}},
// 位移
{Ast::Operator::ShiftLeft, {110, 111}},
{Ast::Operator::ShiftRight, {110, 111}},
// 加减
{Ast::Operator::Add, {120, 121}},
{Ast::Operator::Subtract, {120, 121}},
// 乘除模
{Ast::Operator::Multiply, {130, 131}},
{Ast::Operator::Divide, {130, 131}},
{Ast::Operator::Modulo, {130, 131}},
// 幂运算 - 右结合
{Ast::Operator::Power, {140, 139}}, // leftBP > rightBP
}; };
// 赋值 < 三元 < 逻辑或 < 逻辑与 < 位运算 < 比较 < 位移 < 加减 < 乘除 < 幂 < 一元
// 一元运算符的优先级比所有二元运算符都高
const std::unordered_map<Ast::Operator, Parser::Precedence> Parser::unaryOpPrecedence = { const std::unordered_map<Ast::Operator, Parser::Precedence> Parser::unaryOpPrecedence = {
{Ast::Operator::Subtract, 150}, // - {Ast::Operator::Subtract, 150}, // -
{Ast::Operator::BitAnd, 150}, // &
{Ast::Operator::BitNot, 150}, // ~ {Ast::Operator::BitNot, 150}, // ~
{Ast::Operator::Not, 150}, // ! {Ast::Operator::Not, 150}, // !
{Ast::Operator::BitAnd, 150}, // &(取地址)
}; };
Ast::VarDef Parser::__parseVarDef(bool isPublic) Ast::VarDef Parser::__parseVarDef(bool isPublic)