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