Skip to content

Commit

Permalink
support to_string(enum)
Browse files Browse the repository at this point in the history
  • Loading branch information
chloro-pn committed Jun 14, 2024
1 parent fd478a2 commit 18e04d2
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 25 deletions.
18 changes: 9 additions & 9 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ cc_test(
],
)

#cc_binary(
# name = "catch2_test",
# srcs = glob(["catch2_test/*.cc"]),
# copts = WAMON_COPTS,
# deps = [
# "@catch2//:catch2_main",
# ":wamon",
# ],
#)
cc_binary(
name = "catch2_test",
srcs = glob(["catch2_test/*.cc"]),
copts = WAMON_COPTS,
deps = [
"@catch2//:catch2_main",
":wamon",
],
)

cc_binary(
name = "hello_world",
Expand Down
4 changes: 2 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
* 返回类型为void时的return语句优化
* [done] 支持析构函数
* 支持内置函数assert
* 支持 enum to string
* 内置函数放置在wamon包名称中
* [done] 支持 enum to string
* [done] 内置函数放置在wamon包名称中
3 changes: 2 additions & 1 deletion example/register_cpp_function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
#include "wamon/type_checker.h"
#include "wamon/variable.h"

auto my_cpp_func_check(const std::vector<std::unique_ptr<wamon::Type>>& params_type) -> std::unique_ptr<wamon::Type> {
auto my_cpp_func_check(const wamon::PackageUnit&, const std::vector<std::unique_ptr<wamon::Type>>& params_type)
-> std::unique_ptr<wamon::Type> {
if (params_type.size() != 1) {
throw wamon::WamonException("invalid params count {}", params_type.size());
}
Expand Down
7 changes: 5 additions & 2 deletions include/wamon/builtin_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Type;
class FuncCallExpr;
class TypeChecker;
class Interpreter;
class PackageUnit;

namespace detail {

Expand All @@ -35,7 +36,8 @@ void MergeMap(std::unordered_map<KeyType, ValueType>& map, std::unordered_map<Ke
class BuiltinFunctions {
public:
using HandleType = std::function<std::shared_ptr<Variable>(Interpreter&, std::vector<std::shared_ptr<Variable>>&&)>;
using CheckType = std::function<std::unique_ptr<Type>(const std::vector<std::unique_ptr<Type>>& params_type)>;
using CheckType =
std::function<std::unique_ptr<Type>(const PackageUnit&, const std::vector<std::unique_ptr<Type>>& params_type)>;

BuiltinFunctions();

Expand All @@ -45,7 +47,8 @@ class BuiltinFunctions {

BuiltinFunctions& operator=(BuiltinFunctions&&) = default;

std::unique_ptr<Type> TypeCheck(const std::string& name, const std::vector<std::unique_ptr<Type>>& params_type) const;
std::unique_ptr<Type> TypeCheck(const std::string& name, const PackageUnit& pu,
const std::vector<std::unique_ptr<Type>>& params_type) const;

bool Find(const std::string& name) const { return builtin_handles_.find(name) != builtin_handles_.end(); }

Expand Down
2 changes: 2 additions & 0 deletions include/wamon/type_checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class TypeChecker {
friend std::unique_ptr<Type> CheckAndGetTypeForNewExpr(TypeChecker& tc, NewExpr* new_expr);
friend std::unique_ptr<Type> CheckAndGetTypeForAllocExpr(TypeChecker& tc, AllocExpr* alloc_expr);
friend std::unique_ptr<Type> CheckAndGetTypeForDeallocExpr(TypeChecker& tc, DeallocExpr* dealloc_expr);
friend std::unique_ptr<Type> CheckParamTypeAndGetResultTypeForFunction(const TypeChecker& tc,
FuncCallExpr* call_expr);

friend class BuiltinFunctions;

Expand Down
26 changes: 20 additions & 6 deletions src/builtin_functions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "wamon/ast.h"
#include "wamon/exception.h"
#include "wamon/interpreter.h"
#include "wamon/package_unit.h"
#include "wamon/type_checker.h"
#include "wamon/variable.h"

Expand Down Expand Up @@ -48,8 +49,13 @@ static auto _to_string(Interpreter& ip, std::vector<std::shared_ptr<Variable>>&&
result = std::to_string(AsDoubleVariable(v)->GetValue());
} else if (IsBoolType(v->GetType())) {
result = AsBoolVariable(v)->GetValue() == true ? "true" : "false";
} else {
} else if (IsByteType(v->GetType())) {
result.push_back(static_cast<char>(AsByteVariable(v)->GetValue()));
} else {
auto enum_def = ip.GetPackageUnit().FindEnum(v->GetTypeInfo());
assert(enum_def != nullptr);
const auto& enum_item = AsEnumVariable(v)->GetEnumItem();
result = enum_def->GetEnumName() + ":" + enum_item;
}
return std::make_shared<StringVariable>(result, wamon::Variable::ValueCategory::RValue, "");
}
Expand All @@ -61,25 +67,33 @@ static void register_builtin_handles(const std::string& prefix,
handles[prefix + "context_stack"] = _context_stack;
}

static auto _print_check(const std::vector<std::unique_ptr<Type>>& params_type) -> std::unique_ptr<Type> {
static auto _print_check(const PackageUnit& pu, const std::vector<std::unique_ptr<Type>>& params_type)
-> std::unique_ptr<Type> {
return TypeFactory<void>::Get();
}

static auto _context_stack_check(const std::vector<std::unique_ptr<Type>>& params_type) -> std::unique_ptr<Type> {
static auto _context_stack_check(const PackageUnit& pu, const std::vector<std::unique_ptr<Type>>& params_type)
-> std::unique_ptr<Type> {
if (params_type.size() != 0) {
throw WamonException("context_stack type_check error, params_type.size() == {}", params_type.size());
}
return TypeFactory<std::vector<std::string>>::Get();
}

static auto _to_string_check(const std::vector<std::unique_ptr<Type>>& params_type) -> std::unique_ptr<Type> {
static auto _to_string_check(const PackageUnit& pu, const std::vector<std::unique_ptr<Type>>& params_type)
-> std::unique_ptr<Type> {
if (params_type.size() != 1) {
throw WamonException("to_string type_check error ,params_type.size() == {}", params_type.size());
}
auto& type = params_type[0];
if (IsIntType(type) || IsDoubleType(type) || IsBoolType(type) || IsByteType(type)) {
return TypeFactory<std::string>::Get();
}
if (pu.FindEnum(type->GetTypeInfo()) == nullptr) {
throw WamonException("to_string type_check error, invalid type {}", type->GetTypeInfo());
} else {
return TypeFactory<std::string>::Get();
}
throw WamonException("to_string type_check error, type {} cant not be to_string", type->GetTypeInfo());
}

Expand All @@ -97,13 +111,13 @@ void BuiltinFunctions::RegisterWamonBuiltinFunction(BuiltinFunctions& obj) {
register_builtin_handles("wamon$", obj.builtin_handles_);
}

std::unique_ptr<Type> BuiltinFunctions::TypeCheck(const std::string& name,
std::unique_ptr<Type> BuiltinFunctions::TypeCheck(const std::string& name, const PackageUnit& pu,
const std::vector<std::unique_ptr<Type>>& params_type) const {
auto check = builtin_checks_.find(name);
if (check == builtin_checks_.end()) {
throw WamonException("BuiltinFunctions::TypeCheck error, not implemented {} now", name);
}
return check->second(params_type);
return check->second(pu, params_type);
}

} // namespace wamon
5 changes: 3 additions & 2 deletions src/package_unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ void PackageUnit::RegisterCppFunctions(const std::string& name, std::unique_ptr<
}
auto ftype = func_type->Clone();
MoveWrapper<decltype(ftype)> mw(std::move(ftype));
auto check_f = [name = name,
mw = mw](const std::vector<std::unique_ptr<Type>>& params_type) mutable -> std::unique_ptr<Type> {
auto check_f = [name = name, mw = mw](
const PackageUnit&,
const std::vector<std::unique_ptr<Type>>& params_type) mutable -> std::unique_ptr<Type> {
auto func_type = std::move(mw).Get();
auto par_type = GetParamType(func_type);
size_t param_size = par_type.size();
Expand Down
4 changes: 2 additions & 2 deletions src/type_checker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,8 @@ std::unique_ptr<Type> CheckParamTypeAndGetResultTypeForFunction(const TypeChecke
for (auto& each : call_expr->parameters_) {
param_types.push_back(tc.GetExpressionType(each.get()));
}
return tc.GetStaticAnalyzer().GetPackageUnit().GetBuiltinFunctions().TypeCheck(id_expr->GenerateIdent(),
param_types);
return tc.GetStaticAnalyzer().GetPackageUnit().GetBuiltinFunctions().TypeCheck(
id_expr->GenerateIdent(), tc.GetStaticAnalyzer().GetPackageUnit(), param_types);
}
// would calcualte id_expr.type_
std::unique_ptr<Type> find_type = tc.GetExpressionType(call_expr->caller_.get());
Expand Down
25 changes: 25 additions & 0 deletions test/builtin_function_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,29 @@ TEST(builtin_function, context_stack) {
std::string dump_info =
R"_(["__lambda_0main","main$func3","main$func2","main$ms::func_method","main$func1","global"])_";
EXPECT_EQ(v->Print().dump(), dump_info);
}

TEST(builtin_function, to_string) {
using namespace wamon;
std::string script = R"(
package main;
enum Color {
Red;
Blue;
}
)";
Scanner scan;
auto tokens = scan.Scan(script);
auto pu = Parse(tokens);
pu = MergePackageUnits(std::move(pu));

TypeChecker tc(pu);
std::string reason;
EXPECT_EQ(tc.CheckAll(reason), true) << reason;

Interpreter ip(pu);
auto v = ip.ExecExpression(tc, "main", "call wamon::to_string:(enum Color:Red)");
EXPECT_EQ(v->GetTypeInfo(), "string");
EXPECT_EQ(AsStringVariable(v)->GetValue(), "main$Color:Red");
}
3 changes: 2 additions & 1 deletion test/interpreter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,8 @@ TEST(interpreter, register_cpp_function) {

pu.RegisterCppFunctions(
"func111",
[](const std::vector<std::unique_ptr<wamon::Type>>& params_type) -> std::unique_ptr<wamon::Type> {
[](const wamon::PackageUnit&,
const std::vector<std::unique_ptr<wamon::Type>>& params_type) -> std::unique_ptr<wamon::Type> {
if (params_type.size() != 1) {
throw wamon::WamonException("invalid params count {}", params_type.size());
}
Expand Down

0 comments on commit 18e04d2

Please sign in to comment.