forked from PuqiAR/Fig-TreeWalker
support function literal, set builtins to global context. great!
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
47
include/Ast/FunctionLiteralExpr.hpp
Normal file
47
include/Ast/FunctionLiteralExpr.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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, // <=
|
||||
|
||||
Reference in New Issue
Block a user