AI开发C语言应用按步走,表达式计算器calc的第十七步,历史记录、复合赋值、自增自减、条件表达式

AI开发C语言应用按步走,表达式计算器calc的第十七步,历史记录、复合赋值、自增自减、条件表达式
calc17 — 历史记录、复合赋值、自增自减、条件表达式1. 概述本次迭代实现了四个新功能来自 features.md 中的 G1~G4 建议大幅提升 REPL 交互体验和表达式表达能力。新增功能编号功能说明G1REPL 历史记录history命令、!n重复执行、文件持久化G2复合赋值运算符-*/%|^G3自增/自减--前缀和后缀形式G4条件表达式C 风格?:三元运算符2. 变更清单文件操作说明hist.h新建历史记录模块 APIhist_add/hist_get/hist_print/hist_save/hist_loadhist.c新建环形缓冲区100 条~/.calc_history文件持久化parse.h编辑TokenType 新增 14 个INC/DEC/QUESTION/COLON 10 个复合赋值运算符parse.c重写多字符运算符检测---等 20 个--后跟数字时回退为负号eval.c编辑新增parse_conditional层unary增加前缀/--factor增加后缀/--main.c编辑历史记录集成history/!n/自动保存复合赋值处理is_assignment扩展print_help更新Makefile编辑SRC/HDR/OBJ加入hist.c/hist.h/hist.otest.expr编辑新增 6 个条件表达式测试用例总数 106→1123. G1 — REPL 历史记录3.1 环形缓冲区#defineHIST_MAX100staticcharhist_buffer[HIST_MAX][128];staticinthist_num;staticinthist_head;3.2 命令命令说明history显示所有历史记录#1 expr格式!n重新执行第 n 条历史记录3.3 文件持久化启动时从~/.calc_history加载历史退出时自动保存到~/.calc_history去重连续相同的不重复记录4. G2 — 复合赋值运算符4.1 新增 TokenToken运算符运算TOKEN_PLUS_ASSIGNx 5→x x 5TOKEN_MINUS_ASSIGN-x - 5→x x - 5TOKEN_STAR_ASSIGN*x * 5→x x * 5TOKEN_SLASH_ASSIGN/x / 5→x x / 5TOKEN_MOD_ASSIGN%x % 5→x x % 5TOKEN_AND_ASSIGNx 5→x x 5TOKEN_OR_ASSIGN|x | 5→x x | 5TOKEN_XOR_ASSIGN^x ^ 5→x x ^ 54.2 实现在main.c的is_assignment中检测name expr模式apply_compound函数执行复合运算staticdoubleapply_compound(doubleleft,doubleright,TokenType op){switch(op){caseTOKEN_PLUS_ASSIGN:returnleftright;caseTOKEN_MINUS_ASSIGN:returnleft-right;caseTOKEN_STAR_ASSIGN:returnleft*right;// ...}}5. G3 — 自增/自减5.1 前缀形式在parse_unary中处理x和--xcalc x 5 calc x 6先修改变量值再返回新值。5.2 后缀形式在parse_factor中处理x和x--calc x 5 calc x 5 calc x 6先返回旧值再修改变量值。5.3 特殊处理--5被正确解析为双重负号-(-5) 5而非对字面量的自减操作。6. G4 — 条件表达式6.1 文法conditional → or (? expr : conditional)?6.2 优先级条件表达式位于expr和expr_or之间优先级仅高于||。6.3 求值staticdoubleparse_conditional(void){doublecondparse_or();Token tparse_peek();if(t.typeTOKEN_QUESTION){parse_consume();doubletrue_valparse_expr();expect(TOKEN_COLON);doublefalse_valparse_conditional();return(cond!0.0)?true_val:false_val;}returncond;}6.4 示例calc 1 2 ? 3 : 4 3 calc a b ? a : b 条件最大值7. 测试验证$maketestcalc — 测试套件PASS[1](90-18)/315 →39... PASS[107]1?2:3 →2PASS[108]0?2:3 →3PASS[109]12?3:4 →3PASS[110]true?1:0 →1PASS[111]false?1:0 →0PASS[112]1?2 → error112passed,0failed,112total