From 20f39b7eba757b2046b5a67fcc2f70185ec66185 Mon Sep 17 00:00:00 2001 From: PuqiAR Date: Fri, 26 Dec 2025 21:59:52 +0800 Subject: [PATCH] =?UTF-8?q?[Feat]=20=E6=94=AF=E6=8C=81=20+=3D=20-=3D?= =?UTF-8?q?=E7=AD=89=E8=BF=90=E7=AE=97=E7=AC=A6=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ast/astBase.hpp | 21 +++++++++++++++++- src/Evaluator/evaluator.cpp | 43 +++++++++++++++++++++++++++++++++++++ src/Parser/parser.cpp | 6 ++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/Ast/astBase.hpp b/src/Ast/astBase.hpp index 4397f77..d64a165 100644 --- a/src/Ast/astBase.hpp +++ b/src/Ast/astBase.hpp @@ -222,7 +222,13 @@ namespace Fig::Ast ShiftRight, // >> // 赋值表达式 - Assign, // = + Assign, // = + PlusAssign, // += + MinusAssign, // -= + AsteriskAssign, // *= + SlashAssign, // /= + PercentAssign, // %= + CaretAssign, // ^= // Walrus, // := }; @@ -255,6 +261,13 @@ namespace Fig::Ast Operator::ShiftLeft, Operator::ShiftRight, + Operator::Assign, + Operator::PlusAssign, + Operator::MinusAssign, + Operator::AsteriskAssign, + Operator::SlashAssign, + Operator::CaretAssign + // Operator::Walrus, // Operator::Dot }; @@ -297,6 +310,12 @@ namespace Fig::Ast // 赋值表达式 {TokenType::Assign, Operator::Assign}, + {TokenType::PlusEqual, Operator::PlusAssign}, + {TokenType::MinusEqual, Operator::MinusAssign}, + {TokenType::AsteriskEqual, Operator::AsteriskAssign}, + {TokenType::SlashEqual, Operator::SlashAssign}, + {TokenType::PercentEqual, Operator::PercentAssign}, + {TokenType::CaretEqual, Operator::CaretAssign}, // {TokenType::Walrus, Operator::Walrus}, }; // := diff --git a/src/Evaluator/evaluator.cpp b/src/Evaluator/evaluator.cpp index 1dc7bd4..78abddd 100644 --- a/src/Evaluator/evaluator.cpp +++ b/src/Evaluator/evaluator.cpp @@ -289,12 +289,55 @@ namespace Fig ObjectPtr rhs = eval(rexp, ctx); return std::make_shared(shift_right(*lhs, *rhs)); } + case Operator::Assign: { LvObject lv = evalLv(lexp, ctx); ObjectPtr rhs = eval(rexp, ctx); lv.set(rhs); return rhs; } + case Operator::PlusAssign: { + LvObject lv = evalLv(lexp, ctx); + ObjectPtr rhs = eval(rexp, ctx); + lv.set(std::make_shared( + *(lv.get()) + *rhs + )); + return rhs; + } + case Operator::MinusAssign: { + LvObject lv = evalLv(lexp, ctx); + ObjectPtr rhs = eval(rexp, ctx); + lv.set(std::make_shared( + *(lv.get()) - *rhs)); + return rhs; + } + case Operator::AsteriskAssign: { + LvObject lv = evalLv(lexp, ctx); + ObjectPtr rhs = eval(rexp, ctx); + lv.set(std::make_shared( + *(lv.get()) * (*rhs))); + return rhs; + } + case Operator::SlashAssign: { + LvObject lv = evalLv(lexp, ctx); + ObjectPtr rhs = eval(rexp, ctx); + lv.set(std::make_shared( + *(lv.get()) / *rhs)); + return rhs; + } + case Operator::PercentAssign: { + LvObject lv = evalLv(lexp, ctx); + ObjectPtr rhs = eval(rexp, ctx); + lv.set(std::make_shared( + *(lv.get()) / *rhs)); + return rhs; + } + // case Operator::CaretAssign: { + // LvObject lv = evalLv(lexp, ctx); + // ObjectPtr rhs = eval(rexp, ctx); + // lv.set(std::make_shared( + // *(lv.get()) ^ *rhs)); + // } default: throw EvaluatorError(u8"UnsupportedOp", std::format("Unsupport operator '{}' for binary", magic_enum::enum_name(op)), bin); } diff --git a/src/Parser/parser.cpp b/src/Parser/parser.cpp index 9991206..bb3aaf0 100644 --- a/src/Parser/parser.cpp +++ b/src/Parser/parser.cpp @@ -35,6 +35,12 @@ namespace Fig {Ast::Operator::ShiftRight, {15, 16}}, {Ast::Operator::Assign, {2, 1}}, // 右结合 + {Ast::Operator::PlusAssign, {2, 1}}, + {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}}, // 右结合