summaryrefslogtreecommitdiff
path: root/src/ast
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast')
-rw-r--r--src/ast/expr.cpp120
-rw-r--r--src/ast/expr.hpp129
2 files changed, 240 insertions, 9 deletions
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp
index 9740a4d9..1246ad29 100644
--- a/src/ast/expr.cpp
+++ b/src/ast/expr.cpp
@@ -52,17 +52,20 @@ SERIALISE_TYPE(Expr::, "Expr", {
#define _(x) if(tag == #x) ptr = new x;
_(ExprNode_Block)
else _(ExprNode_Macro)
- else _(ExprNode_Return)
+ else _(ExprNode_Flow)
else _(ExprNode_Const)
+ else _(ExprNode_Import)
else _(ExprNode_LetBinding)
else _(ExprNode_Assign)
else _(ExprNode_CallPath)
else _(ExprNode_CallMethod)
else _(ExprNode_CallObject)
else _(ExprNode_Match)
+ else _(ExprNode_Loop)
else _(ExprNode_If)
else _(ExprNode_IfLet)
else _(ExprNode_Integer)
+ else _(ExprNode_Closure)
else _(ExprNode_StructLiteral)
else _(ExprNode_Tuple)
else _(ExprNode_NamedValue)
@@ -107,10 +110,40 @@ NODE(ExprNode_Macro, {
os << m_name << "!(" << ")";
})
-NODE(ExprNode_Return, {
+void operator%(::Serialiser& s, const ExprNode_Flow::Type t) {
+ switch(t)
+ {
+ #define _(v) case ExprNode_Flow::v: s << #v; return
+ _(RETURN);
+ _(BREAK);
+ _(CONTINUE);
+ #undef _
+ }
+}
+void operator%(::Deserialiser& s, ExprNode_Flow::Type& t) {
+ ::std::string n;
+ s.item(n);
+ if(0) ;
+ #define _(v) else if(n == #v) t = ExprNode_Flow::v
+ _(RETURN);
+ _(BREAK);
+ _(CONTINUE);
+ #undef _
+ else
+ throw ::std::runtime_error("");
+}
+NODE(ExprNode_Flow, {
+ s % m_type;
+ s.item(m_target);
s.item(m_value);
},{
- os << "return " << *m_value;
+ switch(m_type)
+ {
+ case RETURN: os << "return"; break;
+ case BREAK: os << "break"; break;
+ case CONTINUE: os << "continue"; break;
+ }
+ os << " " << *m_value;
})
NODE(ExprNode_Const, {
@@ -121,6 +154,12 @@ NODE(ExprNode_Const, {
os << "const " << m_name << ": " << m_type << " = " << *m_value;
})
+NODE(ExprNode_Import, {
+ s.item(m_imports);
+},{
+ os << "/* todo: use /*";
+})
+
NODE(ExprNode_LetBinding, {
s.item(m_pat);
s.item(m_type);
@@ -170,6 +209,40 @@ NODE(ExprNode_CallObject, {
os << ")";
})
+void operator%(::Serialiser& s, const ExprNode_Loop::Type t) {
+ switch(t)
+ {
+ #define _(v) case ExprNode_Loop::v: s << #v; return
+ _(LOOP);
+ _(WHILE);
+ _(WHILELET);
+ _(FOR);
+ #undef _
+ }
+}
+void operator%(::Deserialiser& s, ExprNode_Loop::Type& t) {
+ ::std::string n;
+ s.item(n);
+ if(0) ;
+ #define _(v) else if(n == #v) t = ExprNode_Loop::v
+ _(LOOP);
+ _(WHILE);
+ _(WHILELET);
+ _(FOR);
+ #undef _
+ else
+ throw ::std::runtime_error("");
+}
+NODE(ExprNode_Loop, {
+ s % m_type;
+ s.item(m_label);
+ s.item(m_pattern);
+ s.item(m_cond);
+ s.item(m_code);
+},{
+ //os << "LOOP [" << m_label << "] " << m_pattern << " in/= " << m_cond << " " << m_code;
+})
+
SERIALISE_TYPE_A(ExprNode_Match::Arm::, "ExprNode_Match_Arm", {
s.item(m_patterns);
s.item(m_cond);
@@ -224,6 +297,19 @@ NODE(ExprNode_Bool, {
},{
os << m_value;
})
+NODE(ExprNode_String, {
+ s.item(m_value);
+},{
+ os << "\"" << m_value << "\"";
+})
+
+NODE(ExprNode_Closure, {
+ s.item(m_args);
+ s.item(m_return);
+ s.item(m_code);
+},{
+ os << "/* todo: closure */";
+});
NODE(ExprNode_StructLiteral, {
s.item(m_path);
@@ -256,6 +342,13 @@ NODE(ExprNode_Field, {
os << "(" << *m_obj << ")." << m_name;
})
+NODE(ExprNode_Index, {
+ s.item(m_obj);
+ s.item(m_idx);
+},{
+ os << "(" << *m_obj << ")[" << *m_idx << "]";
+})
+
NODE(ExprNode_Deref, {
s.item(m_value);
},{
@@ -279,6 +372,7 @@ void operator%(::Serialiser& s, const ExprNode_BinOp::Type t) {
_(CMPLTE);
_(CMPGT);
_(CMPGTE);
+ _(RANGE);
_(BOOLAND);
_(BOOLOR);
_(BITAND);
@@ -305,6 +399,7 @@ void operator%(::Deserialiser& s, ExprNode_BinOp::Type& t) {
_(CMPLTE);
_(CMPGT);
_(CMPGTE);
+ _(RANGE);
_(BOOLAND);
_(BOOLOR);
_(BITAND);
@@ -404,7 +499,7 @@ NV(ExprNode_Macro,
{
DEBUG("TODO: Macro");
})
-NV(ExprNode_Return,
+NV(ExprNode_Flow,
{
visit(node.m_value);
})
@@ -412,6 +507,7 @@ NV(ExprNode_Const,
{
visit(node.m_value);
})
+NV(ExprNode_Import, {})
NV(ExprNode_LetBinding,
{
// TODO: Handle recurse into Let pattern
@@ -447,6 +543,13 @@ NV(ExprNode_CallObject,
visit(arg);
UNINDENT();
})
+NV(ExprNode_Loop,
+{
+ INDENT();
+ visit(node.m_cond);
+ visit(node.m_code);
+ UNINDENT();
+})
NV(ExprNode_Match,
{
INDENT();
@@ -478,7 +581,11 @@ NV(ExprNode_IfLet,
NV(ExprNode_Integer, {})
NV(ExprNode_Float, {})
NV(ExprNode_Bool, {})
+NV(ExprNode_String, {})
+NV(ExprNode_Closure,
+{
+});
NV(ExprNode_StructLiteral,
{
visit(node.m_base_value);
@@ -499,6 +606,11 @@ NV(ExprNode_Field,
{
visit(node.m_obj);
})
+NV(ExprNode_Index,
+{
+ visit(node.m_obj);
+ visit(node.m_idx);
+})
NV(ExprNode_Deref,
{
visit(node.m_value);
diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp
index 4c6d6b7c..121a1f09 100644
--- a/src/ast/expr.hpp
+++ b/src/ast/expr.hpp
@@ -77,13 +77,21 @@ struct ExprNode_Macro:
};
// Return a value
-struct ExprNode_Return:
+struct ExprNode_Flow:
public ExprNode
{
+ enum Type {
+ RETURN,
+ CONTINUE,
+ BREAK,
+ } m_type;
+ ::std::string m_target;
unique_ptr<ExprNode> m_value;
- ExprNode_Return() {}
- ExprNode_Return(unique_ptr<ExprNode>&& value):
+ ExprNode_Flow() {}
+ ExprNode_Flow(Type type, ::std::string target, unique_ptr<ExprNode>&& value):
+ m_type(type),
+ m_target( move(target) ),
m_value( move(value) )
{
}
@@ -107,6 +115,19 @@ struct ExprNode_Const:
NODE_METHODS();
};
+struct ExprNode_Import:
+ public ExprNode
+{
+ typedef ::std::vector< ::std::pair< ::std::string, AST::Path> > imports_t;
+ imports_t m_imports;
+
+ ExprNode_Import() {}
+ ExprNode_Import(imports_t imports):
+ m_imports( ::std::move(imports) )
+ {}
+
+ NODE_METHODS();
+};
struct ExprNode_LetBinding:
public ExprNode
{
@@ -131,6 +152,9 @@ struct ExprNode_Assign:
NONE,
ADD,
SUB,
+ MUL,
+ DIV,
+ MOD,
} m_op;
unique_ptr<ExprNode> m_slot;
unique_ptr<ExprNode> m_value;
@@ -193,6 +217,42 @@ struct ExprNode_CallObject:
NODE_METHODS();
};
+struct ExprNode_Loop:
+ public ExprNode
+{
+ enum Type {
+ LOOP,
+ WHILE,
+ WHILELET,
+ FOR,
+ } m_type;
+ ::std::string m_label;
+ AST::Pattern m_pattern;
+ unique_ptr<ExprNode> m_cond; // if NULL, loop is a 'loop'
+ unique_ptr<ExprNode> m_code;
+
+ ExprNode_Loop(): m_type(LOOP) {}
+ ExprNode_Loop(::std::string label, unique_ptr<ExprNode> code):
+ m_type(LOOP),
+ m_label( ::std::move(label) ),
+ m_code( ::std::move(code) )
+ {}
+ ExprNode_Loop(::std::string label, unique_ptr<ExprNode> cond, unique_ptr<ExprNode> code):
+ m_type(WHILE),
+ m_label( ::std::move(label) ),
+ m_cond( ::std::move(cond) ),
+ m_code( ::std::move(code) )
+ {}
+ ExprNode_Loop(::std::string label, Type type, AST::Pattern pattern, unique_ptr<ExprNode> val, unique_ptr<ExprNode> code):
+ m_type(type),
+ m_label( ::std::move(label) ),
+ m_pattern( ::std::move(pattern) ),
+ m_cond( ::std::move(val) ),
+ m_code( ::std::move(code) )
+ {}
+ NODE_METHODS();
+};
+
struct ExprNode_Match:
public ExprNode
{
@@ -299,6 +359,39 @@ struct ExprNode_Bool:
NODE_METHODS();
};
+// Literal string
+struct ExprNode_String:
+ public ExprNode
+{
+ ::std::string m_value;
+
+ ExprNode_String() {}
+ ExprNode_String(::std::string value):
+ m_value( ::std::move(value) )
+ {}
+
+ NODE_METHODS();
+};
+
+// Closure / Lambda
+struct ExprNode_Closure:
+ public ExprNode
+{
+ typedef ::std::vector< ::std::pair<AST::Pattern, TypeRef> > args_t;
+
+ args_t m_args;
+ TypeRef m_return;
+ unique_ptr<ExprNode> m_code;
+
+ ExprNode_Closure() {}
+ ExprNode_Closure(args_t args, TypeRef rv, unique_ptr<ExprNode> code):
+ m_args( ::std::move(args) ),
+ m_return( ::std::move(rv) ),
+ m_code( ::std::move(code) )
+ {}
+
+ NODE_METHODS();
+};
// Literal structure
struct ExprNode_StructLiteral:
public ExprNode
@@ -358,6 +451,20 @@ struct ExprNode_Field:
}
NODE_METHODS();
};
+struct ExprNode_Index:
+ public ExprNode
+{
+ ::std::unique_ptr<ExprNode> m_obj;
+ ::std::unique_ptr<ExprNode> m_idx;
+
+ ExprNode_Index() {}
+ ExprNode_Index(::std::unique_ptr<ExprNode> obj, ::std::unique_ptr<ExprNode> idx):
+ m_obj( ::std::move(obj) ),
+ m_idx( ::std::move(idx) )
+ {}
+
+ NODE_METHODS();
+};
// Pointer dereference
struct ExprNode_Deref:
@@ -401,6 +508,8 @@ struct ExprNode_BinOp:
CMPLTE,
CMPGT,
CMPGTE,
+
+ RANGE,
BOOLAND,
BOOLOR,
@@ -470,13 +579,15 @@ public:
virtual void visit(const nt& node) = 0*/
NT(ExprNode_Block);
NT(ExprNode_Macro);
- NT(ExprNode_Return);
+ NT(ExprNode_Flow);
NT(ExprNode_Const);
+ NT(ExprNode_Import);
NT(ExprNode_LetBinding);
NT(ExprNode_Assign);
NT(ExprNode_CallPath);
NT(ExprNode_CallMethod);
NT(ExprNode_CallObject);
+ NT(ExprNode_Loop);
NT(ExprNode_Match);
NT(ExprNode_If);
NT(ExprNode_IfLet);
@@ -484,11 +595,14 @@ public:
NT(ExprNode_Integer);
NT(ExprNode_Float);
NT(ExprNode_Bool);
+ NT(ExprNode_String);
+ NT(ExprNode_Closure);
NT(ExprNode_StructLiteral);
NT(ExprNode_Tuple);
NT(ExprNode_NamedValue);
NT(ExprNode_Field);
+ NT(ExprNode_Index);
NT(ExprNode_Deref);
NT(ExprNode_Cast);
NT(ExprNode_BinOp);
@@ -508,13 +622,15 @@ public:
virtual void visit(const nt& node) override*/
NT(ExprNode_Block);
NT(ExprNode_Macro);
- NT(ExprNode_Return);
+ NT(ExprNode_Flow);
NT(ExprNode_Const);
+ NT(ExprNode_Import);
NT(ExprNode_LetBinding);
NT(ExprNode_Assign);
NT(ExprNode_CallPath);
NT(ExprNode_CallMethod);
NT(ExprNode_CallObject);
+ NT(ExprNode_Loop);
NT(ExprNode_Match);
NT(ExprNode_If);
NT(ExprNode_IfLet);
@@ -522,11 +638,14 @@ public:
NT(ExprNode_Integer);
NT(ExprNode_Float);
NT(ExprNode_Bool);
+ NT(ExprNode_String);
+ NT(ExprNode_Closure);
NT(ExprNode_StructLiteral);
NT(ExprNode_Tuple);
NT(ExprNode_NamedValue);
NT(ExprNode_Field);
+ NT(ExprNode_Index);
NT(ExprNode_Deref);
NT(ExprNode_Cast);
NT(ExprNode_BinOp);