修复了parser解析initexpr模式判断错误的问题。修复标准库改名忘改的问题

This commit is contained in:
2026-02-04 20:34:35 +08:00
parent b4b6d409b5
commit 50ca68b1a4
4 changed files with 128 additions and 20 deletions

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -1,3 +1,4 @@
#include "Ast/Expressions/InitExpr.hpp"
#include <Ast/Expressions/VarExpr.hpp>
#include <Ast/Statements/ErrorFlow.hpp>
#include <Ast/Statements/ImplementSt.hpp>
@@ -6,6 +7,7 @@
#include <Error/error.hpp>
#include <Token/token.hpp>
#include <Parser/parser.hpp>
#include <memory>
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<Ast::VarExprAst>(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<std::pair<FString, Ast::Expression>> nargs;
for (auto &[name, exp] : args)
{
const Ast::VarExpr var = std::static_pointer_cast<Ast::VarExprAst>(exp);
nargs.push_back({var->name, exp});
}
args = nargs;
}
}
expect(TokenType::RightBrace);
next(); // consume `}`
return makeAst<Ast::InitExprAst>(structe, args, static_cast<Ast::InitExprAst::InitMode>(mode));