修复了parser解析initexpr模式判断错误的问题。修复标准库改名忘改的问题
This commit is contained in:
@@ -2,3 +2,14 @@ import std.io;
|
|||||||
|
|
||||||
import token {Token, TokenType};
|
import token {Token, TokenType};
|
||||||
import tokenizer {Tokenizer};
|
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);
|
||||||
|
}
|
||||||
@@ -8,13 +8,95 @@ Copyright (C) 2020-2026 PuqiAR
|
|||||||
|
|
||||||
import token {Token, TokenType};
|
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
|
public struct Tokenizer
|
||||||
{
|
{
|
||||||
src: String = "";
|
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
|
public func TokenizeAll() -> List
|
||||||
{
|
{
|
||||||
var output := [];
|
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;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
Copyright © 2025 PuqiAR. All rights reserved.
|
Copyright © 2025 PuqiAR. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import std.value; // `type` function and string_from
|
// import std.value; // `type` function and string_from
|
||||||
|
|
||||||
|
|
||||||
struct FormatError
|
struct FormatError
|
||||||
@@ -37,7 +37,7 @@ public func format(objects ...) -> Any
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fmt := objects[0];
|
var fmt := objects[0];
|
||||||
var fmtType := value.type(fmt);
|
var fmtType := type(fmt);
|
||||||
if fmtType != "String"
|
if fmtType != "String"
|
||||||
{
|
{
|
||||||
throw new FormatError{"arg 0 (fmt) must be String type, got " + fmtType};
|
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"};
|
throw new FormatError{"require enough format expression"};
|
||||||
}
|
}
|
||||||
|
|
||||||
result += value.string_from(objects[argIndex]);
|
result += objects[argIndex] as String;
|
||||||
argIndex += 1;
|
argIndex += 1;
|
||||||
|
|
||||||
i = endIndex + 1;
|
i = endIndex + 1;
|
||||||
@@ -116,7 +116,7 @@ public func format(objects ...) -> Any
|
|||||||
|
|
||||||
public func formatByListArgs(objects) -> Any
|
public func formatByListArgs(objects) -> Any
|
||||||
{
|
{
|
||||||
if value.type(objects) != "List"
|
if not (objects is List)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ if objects.length() < 1
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fmt := objects[0];
|
var fmt := objects[0];
|
||||||
var fmtType := value.type(fmt);
|
var fmtType := type(fmt);
|
||||||
if fmtType != "String"
|
if fmtType != "String"
|
||||||
{
|
{
|
||||||
throw new FormatError{"arg 0 (fmt) must be String type, got " + fmtType};
|
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"};
|
throw new FormatError{"require enough format expression"};
|
||||||
}
|
}
|
||||||
|
|
||||||
result += value.string_from(objects[argIndex]);
|
result += objects[argIndex] as String;
|
||||||
argIndex += 1;
|
argIndex += 1;
|
||||||
|
|
||||||
i = endIndex + 1;
|
i = endIndex + 1;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "Ast/Expressions/InitExpr.hpp"
|
||||||
#include <Ast/Expressions/VarExpr.hpp>
|
#include <Ast/Expressions/VarExpr.hpp>
|
||||||
#include <Ast/Statements/ErrorFlow.hpp>
|
#include <Ast/Statements/ErrorFlow.hpp>
|
||||||
#include <Ast/Statements/ImplementSt.hpp>
|
#include <Ast/Statements/ImplementSt.hpp>
|
||||||
@@ -6,6 +7,7 @@
|
|||||||
#include <Error/error.hpp>
|
#include <Error/error.hpp>
|
||||||
#include <Token/token.hpp>
|
#include <Token/token.hpp>
|
||||||
#include <Parser/parser.hpp>
|
#include <Parser/parser.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace Fig
|
namespace Fig
|
||||||
{
|
{
|
||||||
@@ -881,10 +883,6 @@ namespace Fig
|
|||||||
if (mode == 0)
|
if (mode == 0)
|
||||||
{
|
{
|
||||||
if (isThis(TokenType::Identifier) && isNext(TokenType::Colon)) { mode = 2; }
|
if (isThis(TokenType::Identifier) && isNext(TokenType::Colon)) { mode = 2; }
|
||||||
else if (isThis(TokenType::Identifier) && (isNext(TokenType::Comma) || isNext(TokenType::RightBrace)))
|
|
||||||
{
|
|
||||||
mode = 3;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mode = 1;
|
mode = 1;
|
||||||
@@ -908,16 +906,6 @@ namespace Fig
|
|||||||
Ast::Expression expr = parseExpression(0, TokenType::Comma, TokenType::RightBrace);
|
Ast::Expression expr = parseExpression(0, TokenType::Comma, TokenType::RightBrace);
|
||||||
args.push_back({fieldName, std::move(expr)});
|
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))
|
if (isThis(TokenType::Comma))
|
||||||
{
|
{
|
||||||
next(); // consume comma
|
next(); // consume comma
|
||||||
@@ -929,6 +917,33 @@ namespace Fig
|
|||||||
currentToken().toString().toBasicString())));
|
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);
|
expect(TokenType::RightBrace);
|
||||||
next(); // consume `}`
|
next(); // consume `}`
|
||||||
return makeAst<Ast::InitExprAst>(structe, args, static_cast<Ast::InitExprAst::InitMode>(mode));
|
return makeAst<Ast::InitExprAst>(structe, args, static_cast<Ast::InitExprAst::InitMode>(mode));
|
||||||
|
|||||||
Reference in New Issue
Block a user