Commit de08b7c5 authored by Alastair Robertson's avatar Alastair Robertson

Add builtins and function calls to grammar

parent bde7225a
...@@ -8,7 +8,15 @@ void Integer::accept(Visitor &v) { ...@@ -8,7 +8,15 @@ void Integer::accept(Visitor &v) {
v.visit(*this); v.visit(*this);
} }
void Variable::accept(Visitor &v) { void Builtin::accept(Visitor &v) {
v.visit(*this);
}
void Call::accept(Visitor &v) {
v.visit(*this);
}
void Map::accept(Visitor &v) {
v.visit(*this); v.visit(*this);
} }
...@@ -24,7 +32,11 @@ void ExprStatement::accept(Visitor &v) { ...@@ -24,7 +32,11 @@ void ExprStatement::accept(Visitor &v) {
v.visit(*this); v.visit(*this);
} }
void AssignStatement::accept(Visitor &v) { void AssignMapStatement::accept(Visitor &v) {
v.visit(*this);
}
void AssignMapCallStatement::accept(Visitor &v) {
v.visit(*this); v.visit(*this);
} }
......
...@@ -27,10 +27,28 @@ public: ...@@ -27,10 +27,28 @@ public:
void accept(Visitor &v) override; void accept(Visitor &v) override;
}; };
class Variable : public Expression { class Builtin : public Expression {
public: public:
explicit Variable(std::string &ident) : ident(ident), vargs(nullptr) { } explicit Builtin(std::string ident) : ident(ident) { }
Variable(std::string &ident, ExpressionList *vargs) : ident(ident), vargs(vargs) { } std::string ident;
void accept(Visitor &v) override;
};
class Call : public Expression {
public:
explicit Call(std::string &func) : func(func), vargs(nullptr) { }
Call(std::string &func, ExpressionList *vargs) : func(func), vargs(vargs) { }
std::string func;
ExpressionList *vargs;
void accept(Visitor &v) override;
};
class Map : public Expression {
public:
explicit Map(std::string &ident) : ident(ident), vargs(nullptr) { }
Map(std::string &ident, ExpressionList *vargs) : ident(ident), vargs(vargs) { }
std::string ident; std::string ident;
ExpressionList *vargs; ExpressionList *vargs;
...@@ -67,15 +85,24 @@ public: ...@@ -67,15 +85,24 @@ public:
void accept(Visitor &v) override; void accept(Visitor &v) override;
}; };
class AssignStatement : public Statement { class AssignMapStatement : public Statement {
public: public:
AssignStatement(Variable *var, Expression *expr) : var(var), expr(expr) { } AssignMapStatement(Map *map, Expression *expr) : map(map), expr(expr) { }
Variable *var; Map *map;
Expression *expr; Expression *expr;
void accept(Visitor &v) override; void accept(Visitor &v) override;
}; };
class AssignMapCallStatement : public Statement {
public:
AssignMapCallStatement(Map *map, Call *call) : map(map), call(call) { }
Map *map;
Call *call;
void accept(Visitor &v) override;
};
class Predicate : public Node { class Predicate : public Node {
public: public:
explicit Predicate(Expression *expr) : expr(expr) { } explicit Predicate(Expression *expr) : expr(expr) { }
...@@ -113,11 +140,14 @@ class Visitor { ...@@ -113,11 +140,14 @@ class Visitor {
public: public:
virtual ~Visitor() { } virtual ~Visitor() { }
virtual void visit(Integer &integer) = 0; virtual void visit(Integer &integer) = 0;
virtual void visit(Variable &var) = 0; virtual void visit(Builtin &builtin) = 0;
virtual void visit(Call &call) = 0;
virtual void visit(Map &map) = 0;
virtual void visit(Binop &binop) = 0; virtual void visit(Binop &binop) = 0;
virtual void visit(Unop &unop) = 0; virtual void visit(Unop &unop) = 0;
virtual void visit(ExprStatement &expr) = 0; virtual void visit(ExprStatement &expr) = 0;
virtual void visit(AssignStatement &assignment) = 0; virtual void visit(AssignMapStatement &assignment) = 0;
virtual void visit(AssignMapCallStatement &assignment) = 0;
virtual void visit(Predicate &pred) = 0; virtual void visit(Predicate &pred) = 0;
virtual void visit(Probe &probe) = 0; virtual void visit(Probe &probe) = 0;
virtual void visit(Program &program) = 0; virtual void visit(Program &program) = 0;
......
...@@ -11,14 +11,24 @@ void Codegen::visit(Integer &integer) ...@@ -11,14 +11,24 @@ void Codegen::visit(Integer &integer)
expr_ = ConstantInt::get(module_.getContext(), APInt(64, integer.n)); // TODO fix bit width expr_ = ConstantInt::get(module_.getContext(), APInt(64, integer.n)); // TODO fix bit width
} }
void Codegen::visit(Variable &var) void Codegen::visit(Builtin &builtin)
{
expr_ = b_.getInt64(0);
}
void Codegen::visit(Call &call)
{
expr_ = b_.getInt64(0);
}
void Codegen::visit(Map &map)
{ {
int mapfd; int mapfd;
if (maps_.find(var.ident) == maps_.end()) { if (maps_.find(map.ident) == maps_.end()) {
maps_[var.ident] = std::make_unique<Map>(); maps_[map.ident] = std::make_unique<ebpf::bpftrace::Map>();
} }
mapfd = maps_[var.ident]->mapfd_; mapfd = maps_[map.ident]->mapfd_;
expr_ = b_.getInt32(mapfd); expr_ = b_.getInt64(mapfd);
// CALL(BPF_FUNC_map_lookup_elem) // CALL(BPF_FUNC_map_lookup_elem)
} }
...@@ -68,18 +78,21 @@ void Codegen::visit(ExprStatement &expr) ...@@ -68,18 +78,21 @@ void Codegen::visit(ExprStatement &expr)
expr.expr->accept(*this); expr.expr->accept(*this);
} }
void Codegen::visit(AssignStatement &assignment) void Codegen::visit(AssignMapStatement &assignment)
{ {
Value *var, *val; Value *map, *val;
assignment.var->accept(*this); assignment.map->accept(*this);
var = expr_; map = expr_;
assignment.expr->accept(*this); assignment.expr->accept(*this);
val = expr_; val = expr_;
// b_.CreateStore(val, var);
// CALL(BPF_FUNC_map_update_elem) // CALL(BPF_FUNC_map_update_elem)
} }
void Codegen::visit(AssignMapCallStatement &assignment)
{
}
void Codegen::visit(Predicate &pred) void Codegen::visit(Predicate &pred)
{ {
Function *parent = b_.GetInsertBlock()->getParent(); Function *parent = b_.GetInsertBlock()->getParent();
......
...@@ -20,11 +20,14 @@ public: ...@@ -20,11 +20,14 @@ public:
{ } { }
void visit(Integer &integer) override; void visit(Integer &integer) override;
void visit(Variable &var) override; void visit(Builtin &builtin) override;
void visit(Call &call) override;
void visit(Map &map) override;
void visit(Binop &binop) override; void visit(Binop &binop) override;
void visit(Unop &unop) override; void visit(Unop &unop) override;
void visit(ExprStatement &expr) override; void visit(ExprStatement &expr) override;
void visit(AssignStatement &assignment) override; void visit(AssignMapStatement &assignment) override;
void visit(AssignMapCallStatement &assignment) override;
void visit(Predicate &pred) override; void visit(Predicate &pred) override;
void visit(Probe &probe) override; void visit(Probe &probe) override;
void visit(Program &program) override; void visit(Program &program) override;
...@@ -34,8 +37,7 @@ private: ...@@ -34,8 +37,7 @@ private:
Module &module_; Module &module_;
IRBuilder<> b_; IRBuilder<> b_;
Value *expr_ = nullptr; Value *expr_ = nullptr;
std::map<std::string, Value *> vars; std::map<std::string, std::unique_ptr<ebpf::bpftrace::Map>> maps_;
std::map<std::string, std::unique_ptr<Map>> maps_;
}; };
} // namespace ast } // namespace ast
......
...@@ -15,19 +15,26 @@ static ebpf::bpftrace::location loc; ...@@ -15,19 +15,26 @@ static ebpf::bpftrace::location loc;
using namespace ebpf::bpftrace; using namespace ebpf::bpftrace;
%} %}
ident [_a-zA-Z][_a-zA-Z0-9]*
map @[_a-zA-Z0-9]*
int [0-9]+|0[xX][0-9a-fA-F]+
hspace [ \t]
vspace [\n\r]
space {hspace}|{vspace}
%% %%
%{ %{
loc.step(); loc.step();
%} %}
[ \t]+ { loc.step(); } {hspace}+ { loc.step(); }
[\n\r]+ { loc.lines(yyleng); loc.step(); } {vspace}+ { loc.lines(yyleng); loc.step(); }
"//".*$ // Comments "//".*$ // Comments
[_a-zA-Z][_a-zA-Z0-9]* { return Parser::make_IDENT(yytext, loc); } {ident} { return Parser::make_IDENT(yytext, loc); }
[0-9]+ { return Parser::make_INT(strtoul(yytext, NULL, 0), loc); } {map} { return Parser::make_MAP(yytext, loc); }
0[xX][0-9a-fA-F]+ { return Parser::make_INT(strtoul(yytext, NULL, 0), loc); } {int} { return Parser::make_INT(strtoul(yytext, NULL, 0), loc); }
":" { return Parser::make_COLON(loc); } ":" { return Parser::make_COLON(loc); }
";" { return Parser::make_SEMI(loc); } ";" { return Parser::make_SEMI(loc); }
"{" { return Parser::make_LBRACE(loc); } "{" { return Parser::make_LBRACE(loc); }
...@@ -36,7 +43,7 @@ using namespace ebpf::bpftrace; ...@@ -36,7 +43,7 @@ using namespace ebpf::bpftrace;
"]" { return Parser::make_RBRACKET(loc); } "]" { return Parser::make_RBRACKET(loc); }
"(" { return Parser::make_LPAREN(loc); } "(" { return Parser::make_LPAREN(loc); }
")" { return Parser::make_RPAREN(loc); } ")" { return Parser::make_RPAREN(loc); }
\//[ \t\n\r]*[\/\{] { return Parser::make_ENDPRED(loc); } // If "/" is followed by "/" or "{", choose ENDPRED, otherwise DIV \//{space}*[\/\{] { return Parser::make_ENDPRED(loc); } // If "/" is followed by "/" or "{", choose ENDPRED, otherwise DIV
"," { return Parser::make_COMMA(loc); } "," { return Parser::make_COMMA(loc); }
"=" { return Parser::make_ASSIGN(loc); } "=" { return Parser::make_ASSIGN(loc); }
"==" { return Parser::make_EQ(loc); } "==" { return Parser::make_EQ(loc); }
......
...@@ -69,6 +69,7 @@ void yyerror(ebpf::bpftrace::Driver &driver, const char *s); ...@@ -69,6 +69,7 @@ void yyerror(ebpf::bpftrace::Driver &driver, const char *s);
; ;
%token <std::string> IDENT "identifier" %token <std::string> IDENT "identifier"
%token <std::string> MAP "map"
%token <int> INT "integer" %token <int> INT "integer"
%type <ast::ProbeList *> probes %type <ast::ProbeList *> probes
...@@ -76,7 +77,8 @@ void yyerror(ebpf::bpftrace::Driver &driver, const char *s); ...@@ -76,7 +77,8 @@ void yyerror(ebpf::bpftrace::Driver &driver, const char *s);
%type <ast::Probe *> probe %type <ast::Probe *> probe
%type <ast::Statement *> stmt %type <ast::Statement *> stmt
%type <ast::Expression *> expr %type <ast::Expression *> expr
%type <ast::Variable *> var %type <ast::Call *> call
%type <ast::Map *> map
%type <ast::ExpressionList *> vargs %type <ast::ExpressionList *> vargs
%printer { yyoutput << %%; } <*>; %printer { yyoutput << %%; } <*>;
...@@ -116,11 +118,13 @@ stmts : stmts ";" stmt { $$ = $1; $1->push_back($3); } ...@@ -116,11 +118,13 @@ stmts : stmts ";" stmt { $$ = $1; $1->push_back($3); }
; ;
stmt : expr { $$ = new ast::ExprStatement($1); } stmt : expr { $$ = new ast::ExprStatement($1); }
| var "=" expr { $$ = new ast::AssignStatement($1, $3); } | map "=" expr { $$ = new ast::AssignMapStatement($1, $3); }
| map "=" call { $$ = new ast::AssignMapCallStatement($1, $3); }
; ;
expr : INT { $$ = new ast::Integer($1); } expr : INT { $$ = new ast::Integer($1); }
| var { $$ = $1; } | IDENT { $$ = new ast::Builtin($1); }
| map { $$ = $1; }
| "(" expr ")" { $$ = $2; } | "(" expr ")" { $$ = $2; }
| expr EQ expr { $$ = new ast::Binop($1, token::EQ, $3); } | expr EQ expr { $$ = new ast::Binop($1, token::EQ, $3); }
| expr NE expr { $$ = new ast::Binop($1, token::NE, $3); } | expr NE expr { $$ = new ast::Binop($1, token::NE, $3); }
...@@ -142,8 +146,11 @@ expr : INT { $$ = new ast::Integer($1); } ...@@ -142,8 +146,11 @@ expr : INT { $$ = new ast::Integer($1); }
| BNOT expr { $$ = new ast::Unop(token::BNOT, $2); } | BNOT expr { $$ = new ast::Unop(token::BNOT, $2); }
; ;
var : IDENT { $$ = new ast::Variable($1); } call : IDENT "(" ")" { $$ = new ast::Call($1); }
| IDENT "[" vargs "]" { $$ = new ast::Variable($1, $3); } | IDENT "(" vargs ")" { $$ = new ast::Call($1, $3); }
map : MAP { $$ = new ast::Map($1); }
| MAP "[" vargs "]" { $$ = new ast::Map($1, $3); }
; ;
vargs : vargs "," expr { $$ = $1; $1->push_back($3); } vargs : vargs "," expr { $$ = $1; $1->push_back($3); }
......
...@@ -12,14 +12,34 @@ void Printer::visit(Integer &integer) ...@@ -12,14 +12,34 @@ void Printer::visit(Integer &integer)
out_ << indent << "int: " << integer.n << std::endl; out_ << indent << "int: " << integer.n << std::endl;
} }
void Printer::visit(Variable &var) void Printer::visit(Builtin &builtin)
{ {
std::string indent(depth_, ' '); std::string indent(depth_, ' ');
out_ << indent << "var: " << var.ident << std::endl; out_ << indent << "builtin: " << builtin.ident << std::endl;
}
void Printer::visit(Call &call)
{
std::string indent(depth_, ' ');
out_ << indent << "call: " << call.func << std::endl;
++depth_;
if (call.vargs) {
for (Expression *expr : *call.vargs) {
expr->accept(*this);
}
}
--depth_;
}
void Printer::visit(Map &map)
{
std::string indent(depth_, ' ');
out_ << indent << "map: " << map.ident << std::endl;
++depth_; ++depth_;
if (var.vargs) { if (map.vargs) {
for (Expression *expr : *var.vargs) { for (Expression *expr : *map.vargs) {
expr->accept(*this); expr->accept(*this);
} }
} }
...@@ -82,17 +102,28 @@ void Printer::visit(ExprStatement &expr) ...@@ -82,17 +102,28 @@ void Printer::visit(ExprStatement &expr)
--depth_; --depth_;
} }
void Printer::visit(AssignStatement &assignment) void Printer::visit(AssignMapStatement &assignment)
{ {
std::string indent(depth_, ' '); std::string indent(depth_, ' ');
out_ << indent << "=" << std::endl; out_ << indent << "=" << std::endl;
++depth_; ++depth_;
assignment.var->accept(*this); assignment.map->accept(*this);
assignment.expr->accept(*this); assignment.expr->accept(*this);
--depth_; --depth_;
} }
void Printer::visit(AssignMapCallStatement &assignment)
{
std::string indent(depth_, ' ');
out_ << indent << "=" << std::endl;
++depth_;
assignment.map->accept(*this);
assignment.call->accept(*this);
--depth_;
}
void Printer::visit(Predicate &pred) void Printer::visit(Predicate &pred)
{ {
std::string indent(depth_, ' '); std::string indent(depth_, ' ');
......
...@@ -12,11 +12,14 @@ public: ...@@ -12,11 +12,14 @@ public:
explicit Printer(std::ostream &out) : out_(out) { } explicit Printer(std::ostream &out) : out_(out) { }
void visit(Integer &integer) override; void visit(Integer &integer) override;
void visit(Variable &var) override; void visit(Builtin &builtin) override;
void visit(Call &call) override;
void visit(Map &map) override;
void visit(Binop &binop) override; void visit(Binop &binop) override;
void visit(Unop &unop) override; void visit(Unop &unop) override;
void visit(ExprStatement &expr) override; void visit(ExprStatement &expr) override;
void visit(AssignStatement &assignment) override; void visit(AssignMapStatement &assignment) override;
void visit(AssignMapCallStatement &assignment) override;
void visit(Predicate &pred) override; void visit(Predicate &pred) override;
void visit(Probe &probe) override; void visit(Probe &probe) override;
void visit(Program &program) override; void visit(Program &program) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment