support function literal, set builtins to global context. great!

This commit is contained in:
2025-12-20 20:27:36 +08:00
parent b9a98150ae
commit e7ca714a89
19 changed files with 362 additions and 502 deletions

View File

@@ -21,7 +21,7 @@ namespace Fig::Ast
class FunctionCallExpr final : public ExpressionAst
{
public:
FString name;
Expression callee; // 不是 name 了!!
FunctionArguments arg;
FunctionCallExpr()
@@ -29,15 +29,15 @@ namespace Fig::Ast
type = AstType::FunctionCall;
}
FunctionCallExpr(FString _name, FunctionArguments _arg) :
name(std::move(_name)), arg(std::move(_arg))
FunctionCallExpr(Expression _callee, FunctionArguments _arg) :
callee(std::move(_callee)), arg(std::move(_arg))
{
type = AstType::FunctionCall;
}
virtual FString toString() override
virtual FString toString() override
{
FString s = name;
FString s = callee->toString();
s += u8"(";
for (size_t i = 0; i < arg.argv.size(); ++i)
{

View File

@@ -9,7 +9,7 @@
namespace Fig::Ast
{
/*
fun greet(greeting, name:String, age:Int, split:String=":") public -> Null
func greet(greeting, name:String, age:Int, split:String=":") -> Null
{
io.println("{}, {}{}{}", greeting, name, split, age);
}
@@ -18,7 +18,7 @@ namespace Fig::Ast
`split` -> default parameter
*/
class FunctionDefSt final : public StatementAst // for define
class FunctionDefSt final : public StatementAst // for definition
{
public:
FString name;

View File

@@ -0,0 +1,47 @@
#pragma once
#include <Ast/astBase.hpp>
#include <Ast/functionParameters.hpp>
#include <fig_string.hpp>
#include <variant>
namespace Fig::Ast
{
class FunctionLiteralExprAst final : public ExpressionAst
{
public:
FunctionParameters paras;
std::variant<BlockStatement, Expression> body;
FunctionLiteralExprAst(FunctionParameters _paras, BlockStatement _body) :
paras(std::move(_paras)), body(std::move(_body))
{
type = AstType::FunctionLiteralExpr;
}
FunctionLiteralExprAst(FunctionParameters _paras, Expression _exprBody) :
paras(std::move(_paras)), body(std::move(_exprBody))
{
type = AstType::FunctionLiteralExpr;
}
bool isExprMode() const
{
return std::holds_alternative<Expression>(body);
}
BlockStatement &getBlockBody()
{
return std::get<BlockStatement>(body);
}
Expression &getExprBody()
{
return std::get<Expression>(body);
}
~FunctionLiteralExprAst() = default;
};
using FunctionLiteralExpr = std::shared_ptr<FunctionLiteralExprAst>;
} // namespace Fig::Ast

View File

@@ -1,43 +0,0 @@
#pragma once
#include <Ast/astBase.hpp>
#include <Ast/functionParameters.hpp>
#include <Value/Type.hpp>
#include <fig_string.hpp>
namespace Fig::Ast
{
class LambdaExprAst : public ExpressionAst
{
public:
/*
Lambda:
fun (greeting) -> Null {}
*/
FunctionParameters paras;
FString retType;
BlockStatement body;
LambdaExprAst() :
retType(ValueType::Null.name)
{
type = AstType::LambdaExpr;
}
LambdaExprAst(FunctionParameters _paras, FString _retType, BlockStatement _body) :
retType(ValueType::Null.name)
{
paras = std::move(_paras);
retType = std::move(_retType);
body = std::move(_body);
}
virtual FString typeName() override
{
return FString(std::format("LambdaExprAst<{}>", retType.toBasicString()));
}
virtual ~LambdaExprAst() = default;
};
using LambdaExpr = std::shared_ptr<LambdaExprAst>;
}; // namespace Fig

View File

@@ -30,6 +30,7 @@ namespace Fig::Ast
TupleExpr, // ()
MapExpr, // {}
InitExpr, // struct{}
FunctionLiteralExpr,
/* Statement */
BlockStatement,
@@ -312,7 +313,7 @@ namespace Fig::Ast
class BlockStatementAst : public StatementAst
{
public:
const std::vector<Statement> stmts;
std::vector<Statement> stmts;
BlockStatementAst()
{
type = AstType::BlockStatement;

View File

@@ -42,9 +42,6 @@ public:
case AstType::IfSt:
printIfSt(std::static_pointer_cast<IfSt>(node), indent);
break;
case AstType::LambdaExpr:
printLambdaExpr(std::static_pointer_cast<LambdaExprAst>(node), indent);
break;
case AstType::TernaryExpr:
printTernaryExpr(std::static_pointer_cast<TernaryExprAst>(node), indent);
break;
@@ -147,8 +144,6 @@ private:
printIndent(indent);
std::cout << "FunctionCall\n";
printIndent(indent + 2);
std::cout << "FuncName: ";
printFString(node->name, 0);
printIndent(indent + 2);
}
@@ -175,14 +170,6 @@ private:
printIndent(indent + 2);
}
void printLambdaExpr(const std::shared_ptr<LambdaExprAst> &node, int indent)
{
printIndent(indent);
std::cout << "LambdaExpr\n"
<< node->toString().toBasicString();
printIndent(indent + 2);
}
void printTernaryExpr(const std::shared_ptr<TernaryExprAst> &node, int indent)
{
printIndent(indent);

View File

@@ -1,12 +1,14 @@
#pragma once
#include <Value/BaseValue.hpp>
#include <Value/Type.hpp>
#include <Ast/functionParameters.hpp>
#include <atomic>
namespace Fig
{
class Value;
/* complex objects */
struct FunctionStruct
{
@@ -15,6 +17,10 @@ namespace Fig
TypeInfo retType;
Ast::BlockStatement body;
bool isBuiltin = false;
std::function<Value(const std::vector<Value> &)> builtin;
int builtinParamCount = -1;
FunctionStruct(Ast::FunctionParameters _paras, TypeInfo _retType, Ast::BlockStatement _body) :
id(nextId()), // 分配唯一 ID
paras(std::move(_paras)),
@@ -23,8 +29,10 @@ namespace Fig
{
}
FunctionStruct(std::function<Value(const std::vector<Value> &)> fn, int argc);
FunctionStruct(const FunctionStruct &other) :
id(other.id), paras(other.paras), retType(other.retType), body(other.body) {}
id(other.id), paras(other.paras), retType(other.retType), body(other.body), isBuiltin(other.isBuiltin), builtin(other.builtin), builtinParamCount(other.builtinParamCount) {}
FunctionStruct &operator=(const FunctionStruct &other) = default;
FunctionStruct(FunctionStruct &&) noexcept = default;
@@ -61,6 +69,8 @@ namespace Fig
data = std::make_unique<FunctionStruct>(
std::move(paras), std::move(ret), std::move(body));
}
Function(std::function<Value(const std::vector<Value> &)> fn, int argc);
bool operator==(const Function &other) const noexcept
{
if (!data || !other.data) return false;

View File

@@ -9,10 +9,10 @@
#include <Ast/FunctionCall.hpp>
#include <Ast/functionParameters.hpp>
#include <Ast/FunctionDefSt.hpp>
#include <Ast/FunctionLiteralExpr.hpp>
#include <Ast/IfSt.hpp>
#include <Ast/ImplementSt.hpp>
#include <Ast/InitExpr.hpp>
#include <Ast/LambdaExpr.hpp>
#include <Ast/StructDefSt.hpp>
#include <Ast/TernaryExpr.hpp>
#include <Ast/UnaryExpr.hpp>

View File

@@ -1,8 +1,6 @@
#pragma once
#include <unordered_map>
#include <optional>
#include <builtins.hpp>
#include <error.hpp>
#include <fig_string.hpp>
#include <ast.hpp>
@@ -84,6 +82,26 @@ namespace Fig
{
globalContext = std::make_shared<Context>(FString(u8"global"));
currentContext = globalContext;
for (auto &[name, fn] : Builtins::builtinFunctions)
{
int argc = Builtins::getBuiltinFunctionParamCount(name);
Function f(fn, argc);
globalContext->def(
name,
ValueType::Function,
AccessModifier::PublicConst,
Value(f));
}
for (auto &[name, val] : Builtins::builtinValues)
{
globalContext->def(
name,
val.getTypeInfo(),
AccessModifier::PublicConst,
val);
}
}
std::shared_ptr<Context> getCurrentContext() { return currentContext; }
@@ -95,6 +113,8 @@ namespace Fig
StatementResult evalStatement(const Ast::Statement &);
Value evalFunctionCall(const Function &, const Ast::FunctionArguments &, FString fnName = u8"<anonymous>");
Value eval(Ast::Expression);
void run();
void printStackTrace() const;

View File

@@ -174,12 +174,19 @@ namespace Fig
return getBindingPower(op).second;
}
// template <class _Tp, class... Args>
// std::shared_ptr<_Tp> makeAst(Args &&...args)
// {
// _Tp node(std::forward<Args>(args)...);
// node.setAAI(currentAAI);
// return std::shared_ptr<_Tp>(new _Tp(node));
// }
template <class _Tp, class... Args>
std::shared_ptr<_Tp> makeAst(Args &&...args)
{
_Tp node(args...);
node.setAAI(currentAAI);
return std::shared_ptr<_Tp>(new _Tp(node));
std::shared_ptr<_Tp> ptr = std::make_shared<_Tp>(std::forward<Args>(args)...);
ptr->setAAI(currentAAI);
return ptr;
}
void expectPeek(TokenType type)
@@ -236,7 +243,6 @@ namespace Fig
Ast::VarDef __parseVarDef(bool); // entry: current is keyword `var` or `const` (isConst: Bool)
Value __parseValue();
Ast::ValueExpr __parseValueExpr();
Ast::FunctionCall __parseFunctionCall(FString);
Ast::FunctionParameters __parseFunctionParameters(); // entry: current is Token::LeftParen
Ast::Statement __parseStatement(); // entry: (idk)
Ast::BlockStatement __parseBlockStatement(); // entry: current is Token::LeftBrace
@@ -246,18 +252,20 @@ namespace Fig
Ast::Return __parseReturn(); // entry: current is Token::Return
Ast::VarExpr __parseVarExpr(FString);
Ast::LambdaExpr __parseLambdaExpr();
Ast::FunctionDef __parseFunctionDef(bool); // entry: current is Token::Identifier (isPublic: Bool)
Ast::StructDef __parseStructDef(bool); // entry: current is Token::Identifier (struct name) arg(isPublic: bool)
Ast::BinaryExpr __parseInfix(Ast::Expression, Ast::Operator, Precedence);
Ast::UnaryExpr __parsePrefix(Ast::Operator, Precedence);
Ast::Expression __parseCall(Ast::Expression);
Ast::ListExpr __parseListExpr(); // entry: current is `[`
Ast::Expression __parseTupleOrParenExpr(); // entry: current is `(`
Ast::MapExpr __parseMapExpr(); // entry: current is `{`
Ast::MapExpr __parseMapExpr(); // entry: current is `{`
Ast::InitExpr __parseInitExpr(FString); // entry: current is `{`, ahead is struct name. arg (struct name : FString)
Ast::Expression __parseTupleOrParenExpr(); // entry: current is `(`
Ast::FunctionLiteralExpr __parseFunctionLiteralExpr(); // entry: current is Token::LParen after Token::Function
Ast::Expression parseExpression(Precedence, TokenType = TokenType::Semicolon, TokenType = TokenType::Semicolon);
std::vector<Ast::AstBase> parseAll();

View File

@@ -22,7 +22,7 @@ namespace Fig
Or, // or
Not, // not
Import, // import
Function, // fun
Function, // func
Variable, // var
Const, // const
Final, // final
@@ -85,7 +85,7 @@ namespace Fig
RightBrace, // }
// LeftArrow, // <-
RightArrow, // ->
// DoubleArrow, // =>
DoubleArrow, // =>
Equal, // ==
NotEqual, // !=
LessEqual, // <=