From 50ca68b1a467a2d395f9cd6085044a66b608a92b Mon Sep 17 00:00:00 2001 From: PuqiAR Date: Wed, 4 Feb 2026 20:34:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86parser=E8=A7=A3?= =?UTF-8?q?=E6=9E=90initexpr=E6=A8=A1=E5=BC=8F=E5=88=A4=E6=96=AD=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=A0=87=E5=87=86=E5=BA=93=E6=94=B9=E5=90=8D=E5=BF=98=E6=94=B9?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ExampleCodes/FigFig/main.fig | 11 +++ ExampleCodes/FigFig/tokenizer.fig | 82 ++++++++++++++++++++ src/Module/Library/std/formater/formater.fig | 12 +-- src/Parser/parser.cpp | 43 ++++++---- 4 files changed, 128 insertions(+), 20 deletions(-) diff --git a/ExampleCodes/FigFig/main.fig b/ExampleCodes/FigFig/main.fig index e42d173..d89c6b7 100644 --- a/ExampleCodes/FigFig/main.fig +++ b/ExampleCodes/FigFig/main.fig @@ -2,3 +2,14 @@ import std.io; import token {Token, TokenType}; import tokenizer {Tokenizer}; + +const src := "abc egaD"; +const tokenizer := new Tokenizer{src}; + +const result := tokenizer.TokenizeAll(); + +for var i := 0; i < result.length(); i += 1 +{ + const tok := result[i]; + io.printf("{}: {}\n", tok.literal, tok.type); +} \ No newline at end of file diff --git a/ExampleCodes/FigFig/tokenizer.fig b/ExampleCodes/FigFig/tokenizer.fig index 8d4ecb5..6720507 100644 --- a/ExampleCodes/FigFig/tokenizer.fig +++ b/ExampleCodes/FigFig/tokenizer.fig @@ -8,13 +8,95 @@ Copyright (C) 2020-2026 PuqiAR import token {Token, TokenType}; +func list_contains(lst: List, value: Any) -> Bool +{ + for var i := 0; i < lst.length(); i += 1 + { + if lst[i] == value + { + return true; + } + } + return false; +} + +func isspace(c: String) -> Bool +{ + return c == " " || c == "\n" || c == "\t"; +} + +func isalpha(c: String) -> Bool +{ + const alb := [ + "a", "b", "c", "d", + "e", "f", "g", "h", + "i", "j", "k", "l", + "m", "n", "o", "p", + "q", "r", "s", "t", + "u", "v", "w", "x", + "y", "z", + "A", "B", "C", "D", + "E", "F", "G", "H", + "I", "J", "K", "L", + "M", "N", "O", "P", + "Q", "R", "S", "T", + "U", "V", "W", "X", + "Y", "Z" + ]; + return list_contains(alb, c); +} + + public struct Tokenizer { src: String = ""; + idx: Int = 0; + + func next() -> Null + { + idx += 1; + } + + func hasNext() -> Bool + { + return idx < src.length(); + } + + func produce() -> String + { + const tmp := src[idx]; + idx += 1; + return tmp; + } + + func current() -> String + { + return src[idx]; + } public func TokenizeAll() -> List { var output := []; + + const push := func (tok: Token) => output.push(tok); + + while hasNext() + { + while hasNext() && isspace(current()) + { + next(); + } + if isalpha(current()) + { + var identi := ""; + while hasNext() && isalpha(current()) + { + identi += produce(); + } + push(new Token{identi, TokenType.Identifier}); + } + } + return output; } } \ No newline at end of file diff --git a/src/Module/Library/std/formater/formater.fig b/src/Module/Library/std/formater/formater.fig index 41e89e7..2588674 100644 --- a/src/Module/Library/std/formater/formater.fig +++ b/src/Module/Library/std/formater/formater.fig @@ -5,7 +5,7 @@ Copyright © 2025 PuqiAR. All rights reserved. */ -import std.value; // `type` function and string_from +// import std.value; // `type` function and string_from struct FormatError @@ -37,7 +37,7 @@ public func format(objects ...) -> Any } var fmt := objects[0]; - var fmtType := value.type(fmt); + var fmtType := type(fmt); if fmtType != "String" { throw new FormatError{"arg 0 (fmt) must be String type, got " + fmtType}; @@ -88,7 +88,7 @@ public func format(objects ...) -> Any throw new FormatError{"require enough format expression"}; } - result += value.string_from(objects[argIndex]); + result += objects[argIndex] as String; argIndex += 1; i = endIndex + 1; @@ -116,7 +116,7 @@ public func format(objects ...) -> Any public func formatByListArgs(objects) -> Any { - if value.type(objects) != "List" + if not (objects is List) { return null; } @@ -126,7 +126,7 @@ if objects.length() < 1 } var fmt := objects[0]; - var fmtType := value.type(fmt); + var fmtType := type(fmt); if fmtType != "String" { throw new FormatError{"arg 0 (fmt) must be String type, got " + fmtType}; @@ -177,7 +177,7 @@ if objects.length() < 1 throw new FormatError{"require enough format expression"}; } - result += value.string_from(objects[argIndex]); + result += objects[argIndex] as String; argIndex += 1; i = endIndex + 1; diff --git a/src/Parser/parser.cpp b/src/Parser/parser.cpp index 88e9321..a750b21 100644 --- a/src/Parser/parser.cpp +++ b/src/Parser/parser.cpp @@ -1,3 +1,4 @@ +#include "Ast/Expressions/InitExpr.hpp" #include #include #include @@ -6,6 +7,7 @@ #include #include #include +#include namespace Fig { @@ -881,10 +883,6 @@ namespace Fig if (mode == 0) { if (isThis(TokenType::Identifier) && isNext(TokenType::Colon)) { mode = 2; } - else if (isThis(TokenType::Identifier) && (isNext(TokenType::Comma) || isNext(TokenType::RightBrace))) - { - mode = 3; - } else { mode = 1; @@ -908,16 +906,6 @@ namespace Fig Ast::Expression expr = parseExpression(0, TokenType::Comma, TokenType::RightBrace); args.push_back({fieldName, std::move(expr)}); } - else if (mode == 3) - { - // 3 Person {name, age, sex}; - expect(TokenType::Identifier); - FString fieldName = currentToken().getValue(); - Ast::Expression expr = makeAst(fieldName); - args.push_back({fieldName, std::move(expr)}); - next(); // consume identifier - } - if (isThis(TokenType::Comma)) { next(); // consume comma @@ -929,6 +917,33 @@ namespace Fig currentToken().toString().toBasicString()))); } } + bool shorthand = true; + if (mode == 1) + { + for (auto &[name, exp] : args) + { + if (!name.empty()) + { + shorthand = false; + } + if (exp->getType() != Ast::AstType::VarExpr) + { + shorthand = false; + } + } + if (shorthand) + { + mode = 3; // all are identifiers, so it's shorthand mode, not positional + std::vector> nargs; + for (auto &[name, exp] : args) + { + const Ast::VarExpr var = std::static_pointer_cast(exp); + nargs.push_back({var->name, exp}); + } + args = nargs; + } + } + expect(TokenType::RightBrace); next(); // consume `}` return makeAst(structe, args, static_cast(mode));