From 3a5d40a60aeff79b4baea466ff8d0158a339002b Mon Sep 17 00:00:00 2001 From: chloro <13125187405@163.com> Date: Sun, 16 Jun 2024 05:20:40 +0800 Subject: [PATCH] add doc and remove useless readme now --- README.md | 191 +--------------------------------- doc/builtin_function.md | 0 doc/expr_and_stmt.md | 0 doc/identifier_and_keyword.md | 0 doc/interpreter.md | 0 doc/operator.md | 0 doc/package.md | 61 +++++++++++ doc/register_cpp_function.md | 0 doc/type.md | 0 doc/type_check.md | 0 doc/variable.md | 0 11 files changed, 66 insertions(+), 186 deletions(-) create mode 100644 doc/builtin_function.md create mode 100644 doc/expr_and_stmt.md create mode 100644 doc/identifier_and_keyword.md create mode 100644 doc/interpreter.md create mode 100644 doc/operator.md create mode 100644 doc/package.md create mode 100644 doc/register_cpp_function.md create mode 100644 doc/type.md create mode 100644 doc/type_check.md create mode 100644 doc/variable.md diff --git a/README.md b/README.md index c0d055d..374ecd0 100644 --- a/README.md +++ b/README.md @@ -2,191 +2,10 @@ ![](https://tokei.rs/b1/github/chloro-pn/wamon) ![](https://tokei.rs/b1/github/chloro-pn/wamon?category=files) ![Static Badge](https://img.shields.io/badge/c%2B%2B-20-blue) -一个c++实现的脚本语言,以c++为宿主环境运行。 +Embedded Scripting Language Designed for C++ -## design +## doc +see doc/*.md -* wamon的首要目标是提供与c++丝滑的交互能力,所见即所得、便于调试、类型安全、低阅读门槛、跨平台等特性的优先级均高于追求性能,因此本项目不会使用过多编译优化技术。 - -* wamon的变量是值语义的,变量的生命周期与作用域规则与c++保持一致,wamon不包含gc。 - -* wamon是两阶段的:脚本文本通过词法分析与语法分析后,需要进行语义分析,最后才能执行。 - -* wamon是强类型的,不支持c++中的隐式类型转换。 - -* wamon的使用一般遵循以下格式: - -```c++ - // wamon::Scanner负责词法分析,输入脚本文本,输出tokens - wamon::Scanner scan; - wamon::PackageUnit pu; - wamon::PackageUnit pu2; - auto tokens = scan.Scan(str); - // wamon::Parse函数负责语法分析,输入tokens,输出PackageUnit,每次只能Parse一个Package - pu = wamon::Parse(tokens); - - tokens = scan.Scan(math_str); - pn2 = wamon::Parse(tokens); - // wamon::MergePackageUnits负责将多个Package合并为一个Package,其中涉及重命名和符号定位等工作,即使是一个包也需要进行这一步。 - pu = wamon::MergePackageUnits(std::move(pu), std::move(pu2)); - - // wamon::TypeChecker负责语义分析,其中包括类型分析与上下文相关的语句和表达式的合法性分析等等,这个名字之后需要改,有歧义。 - wamon::TypeChecker tc(pu); - std::string reason; - bool succ = tc.CheckAll(reason); - EXPECT_EQ(succ, true) << reason; - // 通过语义分析后,构造wamon::Interpreter,通过wamon::Interpreter提供的接口执行脚本 - wamon::Interpreter ip(pu); -``` - -## 类型系统 - -##### wamon的类型系统如下: - - 基本类型: - - 内置类型 - - int - - string - - byte - - double - - bool - - void - - 结构体类型 - - 复合类型(类型加工器): - - 指针类型 * `ptr(int)` - - 列表类型 [num] `list(int)` - - 函数类型 <- `f((int, string) -> int)` - -wamon为这些类型提供了以下内置方法(目前这里还没做多少,需要提供更多的方法): -* string:len() -> int -* string:at() -> byte -* string:append(byte|string) -> void -* list(T):at(int) -> T -* list(T):size() -> int -* list(T):insert(int, T) -> void -* list(T):push_back(T) -> void -* list(T):pop_back() -> void -* list(T):resize(int) -> void -* list(T):erase(int) -> void -* list(T):clear() -> void -* list(T):empty() -> bool - -##### 类型转换 -wamon是强类型的,通过双元运算符as进行类型转换工作,目前支持: -* int -> double -* double -> int -* int -> bool -* list(byte) -> string -* struct / struct trait -> struct trait - -## struct、struct trait -wamon通过支持`struct`来支持ADT,struct声明的语法如下: -```c++ -// 数据成员声明在struct块中 -struct struct_name { - type identifier; - type identifier; - ... -} - -// 方法声明在method块中 -method struct_name { - // 可以使用self代指调用该方法的变量 - func method_name(param_list) -> type { - ... - } - ... - // wamon支持调用运算符重载 - operator() (param_list) -> type { - ... - } -} -``` -wamon通过支持`struct trait`来支持运行时多态,struct trait和struct的区别在于:struct trait的方法只有声明没有定义,它只定义了一些struct应该有的数据成员和方法。 - -如果某个`struct A`拥有某个`struct trait B`定义的全部数据成员和方法,那么就称A满足B这种trait。 - -`struct trait`属于wamon的类型系统,因此一个变量可以是`struct trait`类型,只是无法直接构造这个类型的变量,需要从其它类型的变量转换而来。 - -如果`struct A`满足`struct trait B`,那么可以用as运算符将其转换为B类型。 - - -## 值型别、变量定义和new表达式 -wamon有与c++相似的值型别的概念,不过是简化版本,wamon中的变量有两种值型别:左值和右值: -* move运算符可以将左值变量变成右值变量,与c++不同的是,wamon中的move是一个单元运算符。 -* 变量定义表达式的格式:`let var_name : type = expr | (expr_list);`,let定义的变量是左值类型 -* 也可以通过new表达式定义一个匿名的临时变量:`new type(expr_list)`,new定义的变量是右值类型 - -## register cpp functions -wamon提供了如下接口将cpp函数注册到wamon运行时中(不提供类型转换和匹配操作,需要用户自己实现),ct在语义分析阶段调用,用户应该在ct中检查传入的参数类型是否符合要求,如果不符合需要抛出异常。 -ht在运行阶段调用。 - -```c++ - std::string RegisterCppFunctions(const std::string& name, BuiltinFunctions::CheckType ct, - BuiltinFunctions::HandleType ht); - // ... - using HandleType = std::function(std::vector>&&)>; - using CheckType = std::function(const std::vector>& params_type)>; -``` - -你也可以通过下面这个接口注册类型确定的内置函数: -```c++ -void Interpreter::RegisterCppFunctions(const std::string& name, std::unique_ptr func_type, - BuiltinFunctions::HandleType ht); -``` -这种内置函数参与类型分析,可以被赋值给Callable对象,详情见example/register_cpp_function.cc - - -## 函数是一等公民 - -wamon中的函数可以被赋值给变量、可以作为参数和返回值传递,是wamon中的一等公民。 - -wamon通过Callable变量持有原始函数、lambda表达式、重载了()运算符类型的变量。 - -Callable变量是指具有函数类型的变量: - -`let callable_obj : f((int) -> int) = (...); ` - -Callable变量可以像普通变量一样被复制、传递、作为参数和返回值。 - -Callable变量可以出现在函数调用表达式表达式中: - -`call callable_obj:(4); ` - -## hello world -```c++ -#include -#include - -#include "wamon/interpreter.h" -#include "wamon/parser.h" -#include "wamon/scanner.h" -#include "wamon/type_checker.h" -#include "wamon/variable.h" - -int main() { - std::string script = R"( - package main; - - func hello() -> string { - return "hello world"; - } - )"; - - wamon::Scanner scanner; - auto tokens = scanner.Scan(script); - wamon::PackageUnit package_unit = wamon::Parse(tokens); - package_unit = wamon::MergePackageUnits(std::move(package_unit)); - wamon::TypeChecker type_checker(package_unit); - - std::string reason; - bool succ = type_checker.CheckAll(reason); - if (succ == false) { - std::cerr << "type check error : " << reason << std::endl; - return -1; - } - wamon::Interpreter ip(package_unit); - auto ret = ip.CallFunctionByName("main$hello", {}); - std::cout << wamon::AsStringVariable(ret)->GetValue() << std::endl; - return 0; -} -``` \ No newline at end of file +## TODO +Update the readme file after writing the doc \ No newline at end of file diff --git a/doc/builtin_function.md b/doc/builtin_function.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/expr_and_stmt.md b/doc/expr_and_stmt.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/identifier_and_keyword.md b/doc/identifier_and_keyword.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/interpreter.md b/doc/interpreter.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/operator.md b/doc/operator.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/package.md b/doc/package.md new file mode 100644 index 0000000..5dac463 --- /dev/null +++ b/doc/package.md @@ -0,0 +1,61 @@ +### before +关于wamon中`identifier`的概念见 `doc/identifier_and_keyword.md` + +### package +wamon使用包(`package`)的概念组织源码,任何源代码文件必须属于某个包,同时源码文件的第一行有效代码必须是包声明语句,通过该语句声明自己所在的包。 +包声明语句:`package identifier;` +包声明语句之后是0个或多个包导入语句(包导入语句是可选的)。 +包导入语句:`import identifier;` + +接下来是一系列可以在包作用域中定义的实体,包括: +- 全局变量的定义 + 变量定义语句见 `doc/expr_and_stmt.md` +- 结构体的定义 + 结构体定义的语法如下: + ``` + struct struct_name[type: identifier] { + type field_name[type: identifier]; + type field_name[type: identifier]; + ... + } + ``` +- 结构体方法的定义 + 结构体方法定义的语法如下: + ``` + method struct_name[type: identifier] { + func method_name[type: identifier](param_list) -> type + stmt_block + + operator()(param_list) -> type + stmt_block + + destructor() + stmt_block + } + ``` + `method`块中的三类方法均是可选的,其中: + * `stmt_block`的含义见 `doc/expr_and_stmt`。 + * `param_list`的定义是,以逗号分割的`type var_name[type: identifier]`序列。 +- 全局函数的定义 + 全局函数定义的语法如下: + ``` + func (param_list) -> type + stmt_block + ``` +- enum的定义 + enum定义的语法如下: + ``` + enum enum_name[type: identifier] { + enum_item[type: identifier]; + enum_item[type: identifier]; + ... + } + ``` + enum字面量的语法如下:`enum enum_name : enum_item`,例如:`enum Color:Blue` + + ### 实体引用规则 + 当引用同一个包内的实体时可以省略包名称,当引用其他包内的实体时需要在实体前加上包名称和作用域运算符(\:\:),例如: + * `call sort::merge_sort:(param_list)` 调用sort包内的merge_sort函数 + * `enum draw::Color:Red` 声明一个enum常量,enum的类型是包draw内的Color + * `let v : f((int, int) -> int) = math::add;` 定义一个函数类型的变量,变量的值是math包的add全局函数。 + \ No newline at end of file diff --git a/doc/register_cpp_function.md b/doc/register_cpp_function.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/type.md b/doc/type.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/type_check.md b/doc/type_check.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/variable.md b/doc/variable.md new file mode 100644 index 0000000..e69de29