Skip to content

Commit

Permalink
Merge pull request #45 from ValKmjolnir/develop
Browse files Browse the repository at this point in the history
📝 add tutorial about new operators
  • Loading branch information
ValKmjolnir authored Jun 6, 2024
2 parents 5aa99f3 + 0f80dd7 commit 0ffa62e
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 159 deletions.
21 changes: 21 additions & 0 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,27 @@ a &= 0xca;
a |= 0xba;
```

Operator `??` is used to check left hand side value is `nil` or not, if not,
return the right hand side value:

```javascript
print(nil??"should get this string");
```
The example above will print `should get this string`.
Operator `?.` is used to get hash member if left hand side value is not `nil`.
And if left hand side value is not `nil` and not `hash`,
will cause error and exit.
```javascript
var a = nil;
print(a?.try_get); # nil

var a = {try_get: "congrats!"};
print(a?.try_get); # "congrats!"
```
## Definition
As follows.
Expand Down
19 changes: 19 additions & 0 deletions doc/tutorial_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,25 @@ a &= 0xca;
a |= 0xba;
```

`??` 运算符用于检查左侧值是否为 `nil`,如果不是则返回右侧的值:

```javascript
print(nil??"should get this string");
```
上面的例子会输出 `should get this string`
`?.` 运算符用于先检查左侧不为 `nil`,如果左侧不是 `nil` 则尝试获取 hash 的字段。
当然如果左侧此时也不是 `hash` 类型,则报错退出。
```javascript
var a = nil;
print(a?.try_get); # nil

var a = {try_get: "congrats!"};
print(a?.try_get); # "congrats!"
```
## 定义变量
如下所示。
Expand Down
68 changes: 37 additions & 31 deletions src/ast_dumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,13 @@ bool ast_dumper::visit_code_block(code_block* node) {

bool ast_dumper::visit_parameter(parameter* node) {
dump_indent();
std::cout << "parameter " << node->get_parameter_name();
std::cout << "parameter ";
switch(node->get_parameter_type()) {
case parameter::kind::normal_parameter: std::cout << "[normal]"; break;
case parameter::kind::dynamic_parameter: std::cout << "[dynamic]"; break;
case parameter::kind::default_parameter: std::cout << "[default]"; break;
}
std::cout << " " << node->get_parameter_name();
std::cout << format_location(node);
if (node->get_default_value()) {
push_indent();
Expand Down Expand Up @@ -169,23 +175,23 @@ bool ast_dumper::visit_binary_operator(binary_operator* node) {
dump_indent();
std::cout << "binary_operator \"";
switch(node->get_operator_type()) {
case binary_operator::binary_type::add: std::cout << "+"; break;
case binary_operator::binary_type::sub: std::cout << "-"; break;
case binary_operator::binary_type::mult: std::cout << "*"; break;
case binary_operator::binary_type::div: std::cout << "/"; break;
case binary_operator::binary_type::concat: std::cout << "~"; break;
case binary_operator::binary_type::bitwise_and: std::cout << "&"; break;
case binary_operator::binary_type::bitwise_or: std::cout << "|"; break;
case binary_operator::binary_type::bitwise_xor: std::cout << "^"; break;
case binary_operator::binary_type::cmpeq: std::cout << "=="; break;
case binary_operator::binary_type::cmpneq: std::cout << "!="; break;
case binary_operator::binary_type::grt: std::cout << ">"; break;
case binary_operator::binary_type::geq: std::cout << ">="; break;
case binary_operator::binary_type::less: std::cout << "<"; break;
case binary_operator::binary_type::leq: std::cout << "<="; break;
case binary_operator::binary_type::condition_and: std::cout << "and"; break;
case binary_operator::binary_type::condition_or: std::cout << "or"; break;
case binary_operator::binary_type::null_chain: std::cout << "??"; break;
case binary_operator::kind::add: std::cout << "+"; break;
case binary_operator::kind::sub: std::cout << "-"; break;
case binary_operator::kind::mult: std::cout << "*"; break;
case binary_operator::kind::div: std::cout << "/"; break;
case binary_operator::kind::concat: std::cout << "~"; break;
case binary_operator::kind::bitwise_and: std::cout << "&"; break;
case binary_operator::kind::bitwise_or: std::cout << "|"; break;
case binary_operator::kind::bitwise_xor: std::cout << "^"; break;
case binary_operator::kind::cmpeq: std::cout << "=="; break;
case binary_operator::kind::cmpneq: std::cout << "!="; break;
case binary_operator::kind::grt: std::cout << ">"; break;
case binary_operator::kind::geq: std::cout << ">="; break;
case binary_operator::kind::less: std::cout << "<"; break;
case binary_operator::kind::leq: std::cout << "<="; break;
case binary_operator::kind::condition_and: std::cout << "and"; break;
case binary_operator::kind::condition_or: std::cout << "or"; break;
case binary_operator::kind::null_chain: std::cout << "??"; break;
}
std::cout << "\"" << format_location(node);
push_indent();
Expand All @@ -204,9 +210,9 @@ bool ast_dumper::visit_unary_operator(unary_operator* node) {
dump_indent();
std::cout << "unary_operator \"";
switch(node->get_operator_type()) {
case unary_operator::unary_type::negative: std::cout << "-"; break;
case unary_operator::unary_type::logical_not: std::cout << "!"; break;
case unary_operator::unary_type::bitwise_not: std::cout << "~"; break;
case unary_operator::kind::negative: std::cout << "-"; break;
case unary_operator::kind::logical_not: std::cout << "!"; break;
case unary_operator::kind::bitwise_not: std::cout << "~"; break;
}
std::cout << "\"" << format_location(node);
push_indent();
Expand Down Expand Up @@ -320,15 +326,15 @@ bool ast_dumper::visit_assignment_expr(assignment_expr* node) {
dump_indent();
std::cout << "assignment ";
switch(node->get_assignment_type()) {
case assignment_expr::assign_type::add_equal: std::cout << "+="; break;
case assignment_expr::assign_type::sub_equal: std::cout << "-="; break;
case assignment_expr::assign_type::mult_equal: std::cout << "*="; break;
case assignment_expr::assign_type::div_equal: std::cout << "/="; break;
case assignment_expr::assign_type::concat_equal: std::cout << "~="; break;
case assignment_expr::assign_type::equal: std::cout << "="; break;
case assignment_expr::assign_type::bitwise_and_equal: std::cout << "&="; break;
case assignment_expr::assign_type::bitwise_or_equal: std::cout << "|="; break;
case assignment_expr::assign_type::bitwise_xor_equal: std::cout << "^="; break;
case assignment_expr::kind::add_equal: std::cout << "+="; break;
case assignment_expr::kind::sub_equal: std::cout << "-="; break;
case assignment_expr::kind::mult_equal: std::cout << "*="; break;
case assignment_expr::kind::div_equal: std::cout << "/="; break;
case assignment_expr::kind::concat_equal: std::cout << "~="; break;
case assignment_expr::kind::equal: std::cout << "="; break;
case assignment_expr::kind::bitwise_and_equal: std::cout << "&="; break;
case assignment_expr::kind::bitwise_or_equal: std::cout << "|="; break;
case assignment_expr::kind::bitwise_xor_equal: std::cout << "^="; break;
}
std::cout << format_location(node);
push_indent();
Expand Down Expand Up @@ -428,7 +434,7 @@ bool ast_dumper::visit_iter_expr(iter_expr* node) {

bool ast_dumper::visit_forei_expr(forei_expr* node) {
dump_indent();
if (node->get_loop_type()==forei_expr::forei_loop_type::foreach) {
if (node->get_loop_type()==forei_expr::kind::foreach) {
std::cout << "foreach";
} else {
std::cout << "forindex";
Expand Down
68 changes: 34 additions & 34 deletions src/nasal_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,14 @@ class code_block: public expr {

class parameter: public expr {
public:
enum class param_type {
enum class kind {
normal_parameter,
default_parameter,
dynamic_parameter
};

private:
param_type type;
kind type;
std::string name;
expr* default_value;

Expand All @@ -256,12 +256,12 @@ class parameter: public expr {
expr(location, expr_type::ast_param),
name(""), default_value(nullptr) {}
~parameter() override;
void set_parameter_type(param_type pt) {type = pt;}
void set_parameter_type(kind pt) {type = pt;}
void set_parameter_name(const std::string& pname) {name = pname;}
void set_default_value(expr* node) {default_value = node;}
param_type get_parameter_type() {return type;}
const std::string& get_parameter_name() const {return name;}
expr* get_default_value() {return default_value;}
auto get_parameter_type() {return type;}
const auto& get_parameter_name() const {return name;}
auto get_default_value() {return default_value;}
void accept(ast_visitor*) override;
};

Expand All @@ -287,7 +287,7 @@ class ternary_operator: public expr {

class binary_operator: public expr {
public:
enum class binary_type {
enum class kind {
add,
sub,
mult,
Expand All @@ -308,7 +308,7 @@ class binary_operator: public expr {
};

private:
binary_type type;
kind type;
expr* left;
expr* right;
number_literal* optimized_const_number;
Expand All @@ -321,29 +321,29 @@ class binary_operator: public expr {
optimized_const_number(nullptr),
optimized_const_string(nullptr) {}
~binary_operator() override;
void set_operator_type(binary_type operator_type) {type = operator_type;}
void set_operator_type(kind operator_type) {type = operator_type;}
void set_left(expr* node) {left = node;}
void set_right(expr* node) {right = node;}
void set_optimized_number(number_literal* node) {optimized_const_number = node;}
void set_optimized_string(string_literal* node) {optimized_const_string = node;}
binary_type get_operator_type() const {return type;}
expr* get_left() {return left;}
expr* get_right() {return right;}
number_literal* get_optimized_number() {return optimized_const_number;}
string_literal* get_optimized_string() {return optimized_const_string;}
auto get_operator_type() const {return type;}
auto get_left() {return left;}
auto get_right() {return right;}
auto get_optimized_number() {return optimized_const_number;}
auto get_optimized_string() {return optimized_const_string;}
void accept(ast_visitor*) override;
};

class unary_operator: public expr {
public:
enum class unary_type {
enum class kind {
negative,
logical_not,
bitwise_not
};

private:
unary_type type;
kind type;
expr* value;
number_literal* optimized_number;

Expand All @@ -352,12 +352,12 @@ class unary_operator: public expr {
expr(location, expr_type::ast_unary),
value(nullptr), optimized_number(nullptr) {}
~unary_operator() override;
void set_operator_type(unary_type operator_type) {type = operator_type;}
void set_operator_type(kind operator_type) {type = operator_type;}
void set_value(expr* node) {value = node;}
void set_optimized_number(number_literal* node) {optimized_number = node;}
unary_type get_operator_type() const {return type;}
expr* get_value() {return value;}
number_literal* get_optimized_number() {return optimized_number;}
auto get_operator_type() const {return type;}
auto get_value() {return value;}
auto get_optimized_number() {return optimized_number;}
void accept(ast_visitor*) override;
};

Expand Down Expand Up @@ -473,7 +473,7 @@ class definition_expr: public expr {

class assignment_expr: public expr {
public:
enum class assign_type {
enum class kind {
equal,
add_equal,
sub_equal,
Expand All @@ -486,7 +486,7 @@ class assignment_expr: public expr {
};

private:
assign_type type;
kind type;
expr* left;
expr* right;

Expand All @@ -495,12 +495,12 @@ class assignment_expr: public expr {
expr(location, expr_type::ast_assign),
left(nullptr), right(nullptr) {}
~assignment_expr() override;
void set_assignment_type(assign_type operator_type) {type = operator_type;}
void set_assignment_type(kind operator_type) {type = operator_type;}
void set_left(expr* node) {left = node;}
void set_right(expr* node) {right = node;}
assign_type get_assignment_type() const {return type;}
expr* get_left() {return left;}
expr* get_right() {return right;}
auto get_assignment_type() const {return type;}
auto get_left() {return left;}
auto get_right() {return right;}
void accept(ast_visitor*) override;
};

Expand Down Expand Up @@ -611,31 +611,31 @@ class iter_expr: public expr {

class forei_expr: public expr {
public:
enum class forei_loop_type {
enum class kind {
foreach,
forindex
};

private:
forei_loop_type type;
kind type;
iter_expr* iterator;
expr* vector_node;
code_block* block;

public:
forei_expr(const span& location):
expr(location, expr_type::ast_forei),
type(forei_loop_type::foreach), iterator(nullptr),
type(kind::foreach), iterator(nullptr),
vector_node(nullptr), block(nullptr) {}
~forei_expr() override;
void set_loop_type(forei_loop_type ft) {type = ft;}
void set_loop_type(kind ft) {type = ft;}
void set_iterator(iter_expr* node) {iterator = node;}
void set_value(expr* node) {vector_node = node;}
void set_code_block(code_block* node) {block = node;}
forei_loop_type get_loop_type() const {return type;}
iter_expr* get_iterator() {return iterator;}
expr* get_value() {return vector_node;}
code_block* get_code_block() {return block;}
auto get_loop_type() const {return type;}
auto get_iterator() {return iterator;}
auto get_value() {return vector_node;}
auto get_code_block() {return block;}
void accept(ast_visitor*) override;
};

Expand Down
Loading

0 comments on commit 0ffa62e

Please sign in to comment.