mirror of https://github.com/exaloop/codon.git
423 lines
18 KiB
C++
423 lines
18 KiB
C++
/*
|
|
* stmt.cpp --- Seq AST statements.
|
|
*
|
|
* (c) Seq project. All rights reserved.
|
|
* This file is subject to the terms and conditions defined in
|
|
* file 'LICENSE', which is part of this source code package.
|
|
*/
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "parser/ast.h"
|
|
#include "parser/visitors/visitor.h"
|
|
|
|
#define ACCEPT_IMPL(T, X) \
|
|
StmtPtr T::clone() const { return make_shared<T>(*this); } \
|
|
void T::accept(X &visitor) { visitor.visit(this); }
|
|
|
|
using fmt::format;
|
|
using std::move;
|
|
|
|
const int INDENT_SIZE = 2;
|
|
|
|
namespace seq {
|
|
namespace ast {
|
|
|
|
Stmt::Stmt() : done(false), age(-1) {}
|
|
Stmt::Stmt(const seq::SrcInfo &s) : done(false) { setSrcInfo(s); }
|
|
string Stmt::toString() const { return toString(-1); }
|
|
|
|
SuiteStmt::SuiteStmt(vector<StmtPtr> stmts, bool ownBlock)
|
|
: Stmt(), ownBlock(ownBlock) {
|
|
for (auto &s : stmts)
|
|
flatten(move(s), this->stmts);
|
|
}
|
|
SuiteStmt::SuiteStmt(const SuiteStmt &stmt)
|
|
: Stmt(stmt), stmts(ast::clone(stmt.stmts)), ownBlock(stmt.ownBlock) {}
|
|
string SuiteStmt::toString(int indent) const {
|
|
string pad = indent >= 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
string s;
|
|
for (int i = 0; i < stmts.size(); i++)
|
|
if (stmts[i])
|
|
s += (i ? pad : "") +
|
|
stmts[i]->toString(indent >= 0 ? indent + INDENT_SIZE : -1) +
|
|
(stmts[i]->done ? "*" : "");
|
|
return format("(suite{}{})", ownBlock ? " #:own " : "",
|
|
s.empty() ? s : " " + pad + s);
|
|
}
|
|
ACCEPT_IMPL(SuiteStmt, ASTVisitor);
|
|
void SuiteStmt::flatten(StmtPtr s, vector<StmtPtr> &stmts) {
|
|
if (!s)
|
|
return;
|
|
auto suite = const_cast<SuiteStmt *>(s->getSuite());
|
|
if (!suite || suite->ownBlock)
|
|
stmts.push_back(s);
|
|
else {
|
|
for (auto &ss : suite->stmts)
|
|
stmts.push_back(ss);
|
|
}
|
|
}
|
|
|
|
string BreakStmt::toString(int) const { return "(break)"; }
|
|
ACCEPT_IMPL(BreakStmt, ASTVisitor);
|
|
|
|
string ContinueStmt::toString(int) const { return "(continue)"; }
|
|
ACCEPT_IMPL(ContinueStmt, ASTVisitor);
|
|
|
|
ExprStmt::ExprStmt(ExprPtr expr) : Stmt(), expr(move(expr)) {}
|
|
ExprStmt::ExprStmt(const ExprStmt &stmt) : Stmt(stmt), expr(ast::clone(stmt.expr)) {}
|
|
string ExprStmt::toString(int) const { return format("(expr {})", expr->toString()); }
|
|
ACCEPT_IMPL(ExprStmt, ASTVisitor);
|
|
|
|
AssignStmt::AssignStmt(ExprPtr lhs, ExprPtr rhs, ExprPtr type, bool shadow)
|
|
: Stmt(), lhs(move(lhs)), rhs(move(rhs)), type(move(type)), shadow(shadow) {}
|
|
AssignStmt::AssignStmt(const AssignStmt &stmt)
|
|
: Stmt(stmt), lhs(ast::clone(stmt.lhs)), rhs(ast::clone(stmt.rhs)),
|
|
type(ast::clone(stmt.type)), shadow(stmt.shadow) {}
|
|
string AssignStmt::toString(int) const {
|
|
return format("(assign {}{}{})", lhs->toString(), rhs ? " " + rhs->toString() : "",
|
|
type ? format(" #:type {}", type->toString()) : "");
|
|
}
|
|
ACCEPT_IMPL(AssignStmt, ASTVisitor);
|
|
|
|
DelStmt::DelStmt(ExprPtr expr) : Stmt(), expr(move(expr)) {}
|
|
DelStmt::DelStmt(const DelStmt &stmt) : Stmt(stmt), expr(ast::clone(stmt.expr)) {}
|
|
string DelStmt::toString(int) const { return format("(del {})", expr->toString()); }
|
|
ACCEPT_IMPL(DelStmt, ASTVisitor);
|
|
|
|
PrintStmt::PrintStmt(vector<ExprPtr> items, bool isInline)
|
|
: Stmt(), items(move(items)), isInline(isInline) {}
|
|
PrintStmt::PrintStmt(const PrintStmt &stmt)
|
|
: Stmt(stmt), items(ast::clone(stmt.items)), isInline(stmt.isInline) {}
|
|
string PrintStmt::toString(int) const {
|
|
return format("(print {}{})", isInline ? "#:inline " : "", combine(items));
|
|
}
|
|
ACCEPT_IMPL(PrintStmt, ASTVisitor);
|
|
|
|
ReturnStmt::ReturnStmt(ExprPtr expr) : Stmt(), expr(move(expr)) {}
|
|
ReturnStmt::ReturnStmt(const ReturnStmt &stmt)
|
|
: Stmt(stmt), expr(ast::clone(stmt.expr)) {}
|
|
string ReturnStmt::toString(int) const {
|
|
return expr ? format("(return {})", expr->toString()) : "(return)";
|
|
}
|
|
ACCEPT_IMPL(ReturnStmt, ASTVisitor);
|
|
|
|
YieldStmt::YieldStmt(ExprPtr expr) : Stmt(), expr(move(expr)) {}
|
|
YieldStmt::YieldStmt(const YieldStmt &stmt) : Stmt(stmt), expr(ast::clone(stmt.expr)) {}
|
|
string YieldStmt::toString(int) const {
|
|
return expr ? format("(yield {})", expr->toString()) : "(yield)";
|
|
}
|
|
ACCEPT_IMPL(YieldStmt, ASTVisitor);
|
|
|
|
AssertStmt::AssertStmt(ExprPtr expr, ExprPtr message)
|
|
: Stmt(), expr(move(expr)), message(move(message)) {}
|
|
AssertStmt::AssertStmt(const AssertStmt &stmt)
|
|
: Stmt(stmt), expr(ast::clone(stmt.expr)), message(ast::clone(stmt.message)) {}
|
|
string AssertStmt::toString(int) const {
|
|
return format("(assert {}{})", expr->toString(), message ? message->toString() : "");
|
|
}
|
|
ACCEPT_IMPL(AssertStmt, ASTVisitor);
|
|
|
|
WhileStmt::WhileStmt(ExprPtr cond, StmtPtr suite, StmtPtr elseSuite)
|
|
: Stmt(), cond(move(cond)), suite(move(suite)), elseSuite(move(elseSuite)) {}
|
|
WhileStmt::WhileStmt(const WhileStmt &stmt)
|
|
: Stmt(stmt), cond(ast::clone(stmt.cond)), suite(ast::clone(stmt.suite)),
|
|
elseSuite(ast::clone(stmt.elseSuite)) {}
|
|
string WhileStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
if (elseSuite && elseSuite->firstInBlock())
|
|
return format("(while-else {}{}{}{}{})", cond->toString(), pad,
|
|
suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1), pad,
|
|
elseSuite->toString(indent >= 0 ? indent + INDENT_SIZE : -1));
|
|
else
|
|
return format("(while {}{}{})", cond->toString(), pad,
|
|
suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1));
|
|
}
|
|
ACCEPT_IMPL(WhileStmt, ASTVisitor);
|
|
|
|
ForStmt::ForStmt(ExprPtr var, ExprPtr iter, StmtPtr suite, StmtPtr elseSuite,
|
|
ExprPtr decorator, vector<CallExpr::Arg> ompArgs)
|
|
: Stmt(), var(move(var)), iter(move(iter)), suite(move(suite)),
|
|
elseSuite(move(elseSuite)), decorator(move(decorator)), ompArgs(move(ompArgs)),
|
|
wrapped(false) {}
|
|
ForStmt::ForStmt(const ForStmt &stmt)
|
|
: Stmt(stmt), var(ast::clone(stmt.var)), iter(ast::clone(stmt.iter)),
|
|
suite(ast::clone(stmt.suite)), elseSuite(ast::clone(stmt.elseSuite)),
|
|
decorator(ast::clone(stmt.decorator)), ompArgs(ast::clone_nop(stmt.ompArgs)),
|
|
wrapped(stmt.wrapped) {}
|
|
string ForStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
string attr;
|
|
if (decorator)
|
|
attr += " " + decorator->toString();
|
|
if (!attr.empty())
|
|
attr = " #:attr" + attr;
|
|
if (elseSuite && elseSuite->firstInBlock())
|
|
return format("(for-else {} {}{}{}{}{}{})", var->toString(), iter->toString(), attr,
|
|
pad, suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1), pad,
|
|
elseSuite->toString(indent >= 0 ? indent + INDENT_SIZE : -1));
|
|
else
|
|
return format("(for {} {}{}{}{})", var->toString(), iter->toString(), attr, pad,
|
|
suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1));
|
|
}
|
|
ACCEPT_IMPL(ForStmt, ASTVisitor);
|
|
|
|
IfStmt::IfStmt(ExprPtr cond, StmtPtr ifSuite, StmtPtr elseSuite)
|
|
: Stmt(), cond(move(cond)), ifSuite(move(ifSuite)), elseSuite(move(elseSuite)) {}
|
|
IfStmt::IfStmt(const IfStmt &stmt)
|
|
: Stmt(stmt), cond(ast::clone(stmt.cond)), ifSuite(ast::clone(stmt.ifSuite)),
|
|
elseSuite(ast::clone(stmt.elseSuite)) {}
|
|
string IfStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
return format("(if {}{}{}{})", cond->toString(), pad,
|
|
ifSuite->toString(indent >= 0 ? indent + INDENT_SIZE : -1),
|
|
elseSuite
|
|
? pad + elseSuite->toString(indent >= 0 ? indent + INDENT_SIZE : -1)
|
|
: "");
|
|
}
|
|
ACCEPT_IMPL(IfStmt, ASTVisitor);
|
|
|
|
MatchStmt::MatchCase MatchStmt::MatchCase::clone() const {
|
|
return {ast::clone(pattern), ast::clone(guard), ast::clone(suite)};
|
|
}
|
|
|
|
MatchStmt::MatchStmt(ExprPtr what, vector<MatchStmt::MatchCase> cases)
|
|
: Stmt(), what(move(what)), cases(move(cases)) {}
|
|
MatchStmt::MatchStmt(const MatchStmt &stmt)
|
|
: Stmt(stmt), what(ast::clone(stmt.what)), cases(ast::clone_nop(stmt.cases)) {}
|
|
string MatchStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
string padExtra = indent > 0 ? string(INDENT_SIZE, ' ') : "";
|
|
vector<string> s;
|
|
for (auto &c : cases)
|
|
s.push_back(format("(case {}{}{}{})", c.pattern->toString(),
|
|
c.guard ? " #:guard " + c.guard->toString() : "", pad + padExtra,
|
|
c.suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1 * 2)));
|
|
return format("(match {}{}{})", what->toString(), pad, join(s, pad));
|
|
}
|
|
ACCEPT_IMPL(MatchStmt, ASTVisitor);
|
|
|
|
ImportStmt::ImportStmt(ExprPtr from, ExprPtr what, vector<Param> args, ExprPtr ret,
|
|
string as, int dots)
|
|
: Stmt(), from(move(from)), what(move(what)), as(move(as)), dots(dots),
|
|
args(move(args)), ret(move(ret)) {}
|
|
ImportStmt::ImportStmt(const ImportStmt &stmt)
|
|
: Stmt(stmt), from(ast::clone(stmt.from)), what(ast::clone(stmt.what)), as(stmt.as),
|
|
dots(stmt.dots), args(ast::clone_nop(stmt.args)), ret(ast::clone(stmt.ret)) {}
|
|
string ImportStmt::toString(int) const {
|
|
vector<string> va;
|
|
for (auto &a : args)
|
|
va.push_back(a.toString());
|
|
return format("(import {}{}{}{}{}{})", from->toString(),
|
|
as.empty() ? "" : format(" #:as '{}", as),
|
|
what ? format(" #:what {}", what->toString()) : "",
|
|
dots ? format(" #:dots {}", dots) : "",
|
|
va.empty() ? "" : format(" #:args ({})", join(va)),
|
|
ret ? format(" #:ret {}", ret->toString()) : "");
|
|
}
|
|
ACCEPT_IMPL(ImportStmt, ASTVisitor);
|
|
|
|
TryStmt::Catch TryStmt::Catch::clone() const {
|
|
return {var, ast::clone(exc), ast::clone(suite)};
|
|
}
|
|
|
|
TryStmt::TryStmt(StmtPtr suite, vector<Catch> catches, StmtPtr finally)
|
|
: Stmt(), suite(move(suite)), catches(move(catches)), finally(move(finally)) {}
|
|
TryStmt::TryStmt(const TryStmt &stmt)
|
|
: Stmt(stmt), suite(ast::clone(stmt.suite)), catches(ast::clone_nop(stmt.catches)),
|
|
finally(ast::clone(stmt.finally)) {}
|
|
string TryStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
string padExtra = indent > 0 ? string(INDENT_SIZE, ' ') : "";
|
|
vector<string> s;
|
|
for (auto &i : catches)
|
|
s.push_back(
|
|
format("(catch {}{}{}{})", !i.var.empty() ? format("#:var '{}", i.var) : "",
|
|
i.exc ? format(" #:exc {}", i.exc->toString()) : "", pad + padExtra,
|
|
i.suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1 * 2)));
|
|
return format(
|
|
"(try{}{}{}{}{})", pad, suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1),
|
|
pad, join(s, pad),
|
|
finally ? format("{}{}", pad,
|
|
finally->toString(indent >= 0 ? indent + INDENT_SIZE : -1))
|
|
: "");
|
|
}
|
|
ACCEPT_IMPL(TryStmt, ASTVisitor);
|
|
|
|
ThrowStmt::ThrowStmt(ExprPtr expr, bool transformed)
|
|
: Stmt(), expr(move(expr)), transformed(transformed) {}
|
|
ThrowStmt::ThrowStmt(const ThrowStmt &stmt)
|
|
: Stmt(stmt), expr(ast::clone(stmt.expr)), transformed(stmt.transformed) {}
|
|
string ThrowStmt::toString(int) const {
|
|
return format("(throw{})", expr ? " " + expr->toString() : "");
|
|
}
|
|
ACCEPT_IMPL(ThrowStmt, ASTVisitor);
|
|
|
|
GlobalStmt::GlobalStmt(string var) : Stmt(), var(move(var)) {}
|
|
string GlobalStmt::toString(int) const { return format("(global '{})", var); }
|
|
ACCEPT_IMPL(GlobalStmt, ASTVisitor);
|
|
|
|
Attr::Attr(const vector<string> &attrs) : module(), parentClass(), isAttribute(false) {
|
|
for (auto &a : attrs)
|
|
set(a);
|
|
}
|
|
void Attr::set(const string &attr) { customAttr.insert(attr); }
|
|
void Attr::unset(const string &attr) { customAttr.erase(attr); }
|
|
bool Attr::has(const string &attr) const { return in(customAttr, attr); }
|
|
|
|
const string Attr::LLVM = "llvm";
|
|
const string Attr::Python = "python";
|
|
const string Attr::Atomic = "atomic";
|
|
const string Attr::Property = "property";
|
|
const string Attr::Internal = "__internal__";
|
|
const string Attr::ForceRealize = "__force__";
|
|
const string Attr::C = "std.internal.attributes.C";
|
|
const string Attr::CVarArg = ".__vararg__";
|
|
const string Attr::Method = ".__method__";
|
|
const string Attr::Capture = ".__capture__";
|
|
const string Attr::Extend = "extend";
|
|
const string Attr::Tuple = "tuple";
|
|
const string Attr::Test = "std.internal.attributes.test";
|
|
|
|
FunctionStmt::FunctionStmt(string name, ExprPtr ret, vector<Param> args, StmtPtr suite,
|
|
Attr attributes, vector<ExprPtr> decorators)
|
|
: Stmt(), name(move(name)), ret(move(ret)), args(move(args)), suite(move(suite)),
|
|
attributes(move(attributes)), decorators(move(decorators)) {}
|
|
FunctionStmt::FunctionStmt(const FunctionStmt &stmt)
|
|
: Stmt(stmt), name(stmt.name), ret(ast::clone(stmt.ret)),
|
|
args(ast::clone_nop(stmt.args)), suite(ast::clone(stmt.suite)),
|
|
attributes(stmt.attributes), decorators(ast::clone(stmt.decorators)) {}
|
|
string FunctionStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
vector<string> as;
|
|
for (auto &a : args)
|
|
as.push_back(a.toString());
|
|
vector<string> attr;
|
|
for (auto &a : decorators)
|
|
attr.push_back(format("(dec {})", a->toString()));
|
|
return format("(fn '{} ({}){}{}{}{})", name, join(as, " "),
|
|
ret ? " #:ret " + ret->toString() : "",
|
|
attr.empty() ? "" : format(" (attr {})", join(attr, " ")), pad,
|
|
suite ? suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1)
|
|
: "(suite)");
|
|
}
|
|
ACCEPT_IMPL(FunctionStmt, ASTVisitor);
|
|
string FunctionStmt::signature() const {
|
|
vector<string> s;
|
|
for (auto &a : args)
|
|
s.push_back(a.type ? a.type->toString() : "-");
|
|
return format("{}", join(s, ":"));
|
|
}
|
|
bool FunctionStmt::hasAttr(const string &attr) const { return attributes.has(attr); }
|
|
|
|
ClassStmt::ClassStmt(string name, vector<Param> args, StmtPtr suite, Attr attributes,
|
|
vector<ExprPtr> decorators, vector<ExprPtr> baseClasses)
|
|
: Stmt(), name(move(name)), args(move(args)), suite(move(suite)),
|
|
attributes(move(attributes)), decorators(move(decorators)),
|
|
baseClasses(move(baseClasses)) {}
|
|
ClassStmt::ClassStmt(const ClassStmt &stmt)
|
|
: Stmt(stmt), name(stmt.name), args(ast::clone_nop(stmt.args)),
|
|
suite(ast::clone(stmt.suite)), attributes(stmt.attributes),
|
|
decorators(ast::clone(stmt.decorators)),
|
|
baseClasses(ast::clone(stmt.baseClasses)) {}
|
|
string ClassStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
vector<string> bases;
|
|
for (auto &b : baseClasses)
|
|
bases.push_back(b->toString());
|
|
string as;
|
|
for (int i = 0; i < args.size(); i++)
|
|
as += (i ? pad : "") + args[i].toString();
|
|
vector<string> attr;
|
|
for (auto &a : decorators)
|
|
attr.push_back(format("(dec {})", a->toString()));
|
|
return format("(class '{}{}{}{}{}{})", name,
|
|
bases.empty() ? "" : format(" (bases {})", join(bases, " ")),
|
|
attr.empty() ? "" : format(" (attr {})", join(attr, " ")),
|
|
as.empty() ? as : pad + as, pad,
|
|
suite ? suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1)
|
|
: "(suite)");
|
|
}
|
|
ACCEPT_IMPL(ClassStmt, ASTVisitor);
|
|
bool ClassStmt::isRecord() const { return hasAttr(Attr::Tuple); }
|
|
bool ClassStmt::hasAttr(const string &attr) const { return attributes.has(attr); }
|
|
|
|
YieldFromStmt::YieldFromStmt(ExprPtr expr) : Stmt(), expr(move(expr)) {}
|
|
YieldFromStmt::YieldFromStmt(const YieldFromStmt &stmt)
|
|
: Stmt(stmt), expr(ast::clone(stmt.expr)) {}
|
|
string YieldFromStmt::toString(int) const {
|
|
return format("(yield-from {})", expr->toString());
|
|
}
|
|
ACCEPT_IMPL(YieldFromStmt, ASTVisitor);
|
|
|
|
WithStmt::WithStmt(vector<ExprPtr> items, vector<string> vars, StmtPtr suite)
|
|
: Stmt(), items(move(items)), vars(move(vars)), suite(move(suite)) {
|
|
assert(items.size() == vars.size());
|
|
}
|
|
WithStmt::WithStmt(vector<pair<ExprPtr, ExprPtr>> itemVarPairs, StmtPtr suite)
|
|
: Stmt(), suite(move(suite)) {
|
|
for (auto &i : itemVarPairs) {
|
|
items.push_back(move(i.first));
|
|
if (i.second) {
|
|
if (!i.second->getId())
|
|
throw;
|
|
vars.push_back(i.second->getId()->value);
|
|
} else {
|
|
vars.push_back("");
|
|
}
|
|
}
|
|
}
|
|
WithStmt::WithStmt(const WithStmt &stmt)
|
|
: Stmt(stmt), items(ast::clone(stmt.items)), vars(stmt.vars),
|
|
suite(ast::clone(stmt.suite)) {}
|
|
string WithStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
vector<string> as;
|
|
for (int i = 0; i < items.size(); i++) {
|
|
as.push_back(!vars[i].empty()
|
|
? format("({} #:var '{})", items[i]->toString(), vars[i])
|
|
: items[i]->toString());
|
|
}
|
|
return format("(with ({}){}{})", join(as, " "), pad,
|
|
suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1));
|
|
}
|
|
ACCEPT_IMPL(WithStmt, ASTVisitor);
|
|
|
|
CustomStmt::CustomStmt(string keyword, ExprPtr expr, StmtPtr suite)
|
|
: Stmt(), keyword(move(keyword)), expr(move(expr)), suite(move(suite)) {}
|
|
CustomStmt::CustomStmt(const CustomStmt &stmt)
|
|
: Stmt(stmt), keyword(stmt.keyword), expr(ast::clone(stmt.expr)),
|
|
suite(ast::clone(stmt.suite)) {}
|
|
string CustomStmt::toString(int indent) const {
|
|
string pad = indent > 0 ? ("\n" + string(indent + INDENT_SIZE, ' ')) : " ";
|
|
return format("(custom-{} {}{}{})", keyword,
|
|
expr ? format(" #:expr {}", expr->toString()) : "", pad,
|
|
suite ? suite->toString(indent >= 0 ? indent + INDENT_SIZE : -1) : "");
|
|
}
|
|
ACCEPT_IMPL(CustomStmt, ASTVisitor);
|
|
|
|
AssignMemberStmt::AssignMemberStmt(ExprPtr lhs, string member, ExprPtr rhs)
|
|
: Stmt(), lhs(move(lhs)), member(move(member)), rhs(move(rhs)) {}
|
|
AssignMemberStmt::AssignMemberStmt(const AssignMemberStmt &stmt)
|
|
: Stmt(stmt), lhs(ast::clone(stmt.lhs)), member(stmt.member),
|
|
rhs(ast::clone(stmt.rhs)) {}
|
|
string AssignMemberStmt::toString(int) const {
|
|
return format("(assign-member {} {} {})", lhs->toString(), member, rhs->toString());
|
|
}
|
|
ACCEPT_IMPL(AssignMemberStmt, ASTVisitor);
|
|
|
|
UpdateStmt::UpdateStmt(ExprPtr lhs, ExprPtr rhs, bool isAtomic)
|
|
: Stmt(), lhs(move(lhs)), rhs(move(rhs)), isAtomic(isAtomic) {}
|
|
UpdateStmt::UpdateStmt(const UpdateStmt &stmt)
|
|
: Stmt(stmt), lhs(ast::clone(stmt.lhs)), rhs(ast::clone(stmt.rhs)),
|
|
isAtomic(stmt.isAtomic) {}
|
|
string UpdateStmt::toString(int) const {
|
|
return format("(update {} {})", lhs->toString(), rhs->toString());
|
|
}
|
|
ACCEPT_IMPL(UpdateStmt, ASTVisitor);
|
|
|
|
} // namespace ast
|
|
} // namespace seq
|