#pragma once #include #include #include #include "global.h" using namespace std; class Statement; class Expression; using Name = string; using StatementList = vector; class Site{ public: string filename; i64 lnum,linex; Site(); Site(const string &filename,i64 lnum,i64 linex); Site addX(i64 dx); }; ostream& operator<<(ostream &os,Site site); class ScopeDef{ public: enum class Type{ direct, lazy, function, // async, }; Type type; StatementList body; vector args; Site site; ScopeDef(); ScopeDef(Type type,const StatementList &body,const vector &args); // ScopeDef(Type type,const StatementList &body,const vector &args); }; ostream& operator<<(ostream &os,const ScopeDef &scope); class Expression{ public: enum class Type{ binop, // name, args[0], args[1] unop, // name, args[0] call, // name, args -- variable reference when args={} dive, // name, args, scope -- variable dive when args={} number, // numval string, // strval scope, // scope cond, // args[0] (cond), args[1] (then), args[2] (else) }; Type type; Name name; vector args; double numval; string strval; ScopeDef scope; Site site; // Expression(); Expression(Type type,const Name &name,const vector &args); // binop, call Expression(Type type,const Name &name,const Expression &arg); // unop Expression(Type type,const Name &name,const vector &args,const ScopeDef &scope); // dive Expression(Type type,double numval); // number Expression(Type type,const string &strval); // string Expression(Type type,const ScopeDef &scope); // scope Expression(Type type,const vector &args); // cond }; ostream& operator<<(ostream &os,const Expression &expr); class Statement{ public: enum class Type{ create, // dstvar, expr assign, // dstvar, expr expression, // expr }; Type type; Name dstvar; Expression expr; Site site; Statement(); Statement(Type type,const Name &dstvar,const Expression &expr); // create, assign Statement(Type type,const Expression &expr); // expr }; ostream& operator<<(ostream &os,const Statement &st); ostream& operator<<(ostream &os,const StatementList &stl);