forked from PuqiAR/Fig-TreeWalker
[Feat] 详细区分左值(LvObject)与右值(RvObject -> ObjectPtr)
[Impl] 重构evaluator.cpp + hpp 全部 [Feat] 增加对于IndexExpr的解析 [Fix][Impl] 现在点运算符不由BinaryExpr负责,增加MemberExpr,单独实现解析 [Impl] 项目目录全部翻修, src/目录下单独文件夹放置每一个模块
This commit is contained in:
152
src/Module/builtins.hpp
Normal file
152
src/Module/builtins.hpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/fig_string.hpp>
|
||||
#include <Value/value.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <print>
|
||||
#include <iostream>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
namespace Builtins
|
||||
{
|
||||
const std::unordered_map<FString, ObjectPtr> builtinValues = {
|
||||
{u8"null", Object::getNullInstance()},
|
||||
{u8"true", Object::getTrueInstance()},
|
||||
{u8"false", Object::getFalseInstance()},
|
||||
};
|
||||
|
||||
using BuiltinFunction = std::function<ObjectPtr(const std::vector<ObjectPtr> &)>;
|
||||
|
||||
const std::unordered_map<FString, int> builtinFunctionArgCounts = {
|
||||
{u8"__fstdout_print", -1}, // variadic
|
||||
{u8"__fstdout_println", -1}, // variadic
|
||||
{u8"__fstdin_read", 0},
|
||||
{u8"__fstdin_readln", 0},
|
||||
{u8"__fvalue_type", 1},
|
||||
{u8"__fvalue_int_parse", 1},
|
||||
{u8"__fvalue_int_from", 1},
|
||||
{u8"__fvalue_double_parse", 1},
|
||||
{u8"__fvalue_double_from", 1},
|
||||
{u8"__fvalue_string_from", 1},
|
||||
};
|
||||
|
||||
const std::unordered_map<FString, BuiltinFunction> builtinFunctions{
|
||||
{u8"__fstdout_print", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
for (auto arg : args)
|
||||
{
|
||||
std::print("{}", arg->toString().toBasicString());
|
||||
}
|
||||
return std::make_shared<Object>(ValueType::IntClass(args.size()));
|
||||
}},
|
||||
{u8"__fstdout_println", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
for (auto arg : args)
|
||||
{
|
||||
std::print("{}", arg->toString().toBasicString());
|
||||
}
|
||||
std::print("\n");
|
||||
return std::make_shared<Object>(ValueType::IntClass(args.size()));
|
||||
}},
|
||||
{u8"__fstdin_read", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
std::string input;
|
||||
std::cin >> input;
|
||||
return std::make_shared<Object>(FString::fromBasicString(input));
|
||||
}},
|
||||
{u8"__fstdin_readln", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
std::string line;
|
||||
std::getline(std::cin, line);
|
||||
return std::make_shared<Object>(FString::fromBasicString(line));
|
||||
}},
|
||||
{u8"__fvalue_type", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
return std::make_shared<Object>(args[0]->getTypeInfo().toString());
|
||||
}},
|
||||
{u8"__fvalue_int_parse", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
FString str = args[0]->as<ValueType::StringClass>();
|
||||
try
|
||||
{
|
||||
ValueType::IntClass val = std::stoi(str.toBasicString());
|
||||
return std::make_shared<Object>(val);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw RuntimeError(FStringView(std::format("Invalid int string for parsing", str.toBasicString())));
|
||||
}
|
||||
}},
|
||||
{u8"__fvalue_int_from", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
ObjectPtr val = args[0];
|
||||
if (val->is<ValueType::DoubleClass>())
|
||||
{
|
||||
return std::make_shared<Object>(static_cast<ValueType::IntClass>(val->as<ValueType::DoubleClass>()));
|
||||
}
|
||||
else if (val->is<ValueType::BoolClass>())
|
||||
{
|
||||
return std::make_shared<Object>(static_cast<ValueType::IntClass>(val->as<ValueType::BoolClass>() ? 1 : 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw RuntimeError(FStringView(std::format("Type '{}' cannot be converted to int", val->getTypeInfo().toString().toBasicString())));
|
||||
}
|
||||
}},
|
||||
{u8"__fvalue_double_parse", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
FString str = args[0]->as<ValueType::StringClass>();
|
||||
try
|
||||
{
|
||||
ValueType::DoubleClass val = std::stod(str.toBasicString());
|
||||
return std::make_shared<Object>(ValueType::DoubleClass(val));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw RuntimeError(FStringView(std::format("Invalid double string for parsing", str.toBasicString())));
|
||||
}
|
||||
}},
|
||||
{u8"__fvalue_double_from", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
ObjectPtr val = args[0];
|
||||
if (val->is<ValueType::IntClass>())
|
||||
{
|
||||
return std::make_shared<Object>(static_cast<ValueType::DoubleClass>(val->as<ValueType::IntClass>()));
|
||||
}
|
||||
else if (val->is<ValueType::BoolClass>())
|
||||
{
|
||||
return std::make_shared<Object>(ValueType::DoubleClass(val->as<ValueType::BoolClass>() ? 1.0 : 0.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw RuntimeError(FStringView(std::format("Type '{}' cannot be converted to double", val->getTypeInfo().toString().toBasicString())));
|
||||
}
|
||||
}},
|
||||
{u8"__fvalue_string_from", [](const std::vector<ObjectPtr> &args) -> ObjectPtr {
|
||||
ObjectPtr val = args[0];
|
||||
return std::make_shared<Object>(val->toString());
|
||||
}},
|
||||
|
||||
};
|
||||
|
||||
inline bool isBuiltinFunction(const FString &name)
|
||||
{
|
||||
return builtinFunctions.find(name) != builtinFunctions.end();
|
||||
}
|
||||
|
||||
inline BuiltinFunction getBuiltinFunction(const FString &name)
|
||||
{
|
||||
auto it = builtinFunctions.find(name);
|
||||
if (it == builtinFunctions.end())
|
||||
{
|
||||
throw RuntimeError(FStringView(std::format("Builtin function '{}' not found", name.toBasicString())));
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline int getBuiltinFunctionParamCount(const FString &name)
|
||||
{
|
||||
auto it = builtinFunctionArgCounts.find(name);
|
||||
if (it == builtinFunctionArgCounts.end())
|
||||
{
|
||||
throw RuntimeError(FStringView(std::format("Builtin function '{}' not found", name.toBasicString())));
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
}; // namespace Builtins
|
||||
}; // namespace Fig
|
||||
47
src/Module/module.hpp
Normal file
47
src/Module/module.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Core/fig_string.hpp>
|
||||
#include <Value/value.hpp>
|
||||
#include <Context/context.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
// class Module
|
||||
// {
|
||||
// public:
|
||||
// const FString name;
|
||||
// const FString spec;
|
||||
// const FString path;
|
||||
|
||||
// std::shared_ptr<Context> context; // module-level context
|
||||
|
||||
// /*
|
||||
|
||||
// import module -> automatically create a module context and call function `init` if exists
|
||||
// all global functions, variables, structs, etc will be stored in module context
|
||||
// then module context will be linked to the current context
|
||||
|
||||
// */
|
||||
// Module(const FString &moduleName, const FString &moduleSpec, const FString &modulePath) :
|
||||
// name(moduleName), spec(moduleSpec), path(modulePath)
|
||||
// {
|
||||
// context = std::make_shared<Context>(FString(std::format("<Module {}>", name.toBasicString())), nullptr);
|
||||
// }
|
||||
|
||||
// bool hasSymbol(const FString &symbolName)
|
||||
// {
|
||||
// return context->contains(symbolName);
|
||||
// }
|
||||
// Object getSymbol(const FString &symbolName)
|
||||
// {
|
||||
// auto valOpt = context->get(symbolName);
|
||||
// if (!valOpt.has_value())
|
||||
// {
|
||||
// throw RuntimeError(FStringView(std::format("Symbol '{}' not found in module '{}'", symbolName.toBasicString(), name.toBasicString())));
|
||||
// }
|
||||
// return valOpt.value();
|
||||
// }
|
||||
// };
|
||||
};
|
||||
Reference in New Issue
Block a user