Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions core/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum ASTType {
AST_ASSERT,
AST_BINARY,
AST_BUILTIN_FUNCTION,
AST_BUILTIN_FUNCTION_BODY,
AST_CONDITIONAL,
AST_DESUGARED_OBJECT,
AST_DOLLAR,
Expand Down Expand Up @@ -76,6 +77,7 @@ static inline std::string ASTTypeToString(ASTType type)
case AST_ASSERT: return "AST_ASSERT";
case AST_BINARY: return "AST_BINARY";
case AST_BUILTIN_FUNCTION: return "AST_BUILTIN_FUNCTION";
case AST_BUILTIN_FUNCTION_BODY: return "AST_BUILTIN_FUNCTION_BODY";
case AST_CONDITIONAL: return "AST_CONDITIONAL";
case AST_DESUGARED_OBJECT: return "AST_DESUGARED_OBJECT";
case AST_DOLLAR: return "AST_DOLLAR";
Expand Down Expand Up @@ -367,16 +369,30 @@ struct Binary : public AST {
}
};

/** Represents the body of a built-in function.
*
* There is no parse rule to build this AST; it is generated during desugaring to represent
* the body of a built-in function.
*/
struct BuiltinFunctionBody : public AST {
std::string name;
// TODO: It would probably be cleaner if this a HeapClosure::Params value.
Identifiers params;
BuiltinFunctionBody(const LocationRange &lr, const std::string &name, const Identifiers &params)
: AST(lr, AST_BUILTIN_FUNCTION_BODY, Fodder{}), name(name), params(params)
{
}
};

/** Represents built-in functions.
*
* There is no parse rule to build this AST. Instead, it is used to build the std object in the
* interpreter.
*/
struct BuiltinFunction : public AST {
std::string name;
Identifiers params;
BuiltinFunction(const LocationRange &lr, const std::string &name, const Identifiers &params)
: AST(lr, AST_BUILTIN_FUNCTION, Fodder{}), name(name), params(params)
const BuiltinFunctionBody *body;
BuiltinFunction(const LocationRange &lr, const BuiltinFunctionBody *body)
: AST(lr, AST_BUILTIN_FUNCTION, Fodder{}), body(body)
{
}
};
Expand Down Expand Up @@ -955,6 +971,7 @@ struct Var : public AST {
*/
class Allocator {
std::map<UString, const Identifier *> internedIdentifiers;
std::map<std::string, const BuiltinFunctionBody *> internedBuiltins;
ASTs allocated;

public:
Expand Down Expand Up @@ -987,6 +1004,18 @@ class Allocator {
internedIdentifiers[name] = r;
return r;
}
template <typename F>
const BuiltinFunctionBody *makeBuiltinBody(const LocationRange &loc, const std::string &name, F&& make_params)
{
auto it = internedBuiltins.find(name);
if (it != internedBuiltins.end()) {
return it->second;
}
const Identifiers params = make_params();
auto r = new BuiltinFunctionBody(loc, name, params);
internedBuiltins[name] = r;
return r;
}
~Allocator()
{
for (auto x : allocated) {
Expand All @@ -997,6 +1026,10 @@ class Allocator {
delete x.second;
}
internedIdentifiers.clear();
for (const auto &x : internedBuiltins) {
delete x.second;
}
internedBuiltins.clear();
}
};

Expand Down
12 changes: 8 additions & 4 deletions core/desugarer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -933,15 +933,19 @@ class Desugarer {
DesugaredObject::Fields &fields = std_obj->fields;
for (unsigned long c = 0; c <= max_builtin; ++c) {
const auto &decl = jsonnet_builtin_decl(c);
Identifiers params;
for (const auto &p : decl.params)
params.push_back(id(p));
auto name = str(decl.name);
auto fn = make<BuiltinFunction>(E, encode_utf8(decl.name), params);
auto name_utf8 = "std:" + encode_utf8(decl.name);
auto fnbody = alloc->makeBuiltinBody(E, name_utf8, [this, &decl]()->Identifiers {
Identifiers params;
for (const auto &p : decl.params)
params.push_back(this->id(p));
return params;
});
auto field = std::find_if(fields.begin(), fields.end(),
[=](const DesugaredObject::Field& f) {
return static_cast<LiteralString*>(f.name)->value == decl.name;
});
auto fn = make<BuiltinFunction>(E, fnbody);
if (field != fields.end()) {
field->body = fn;
} else {
Expand Down
4 changes: 2 additions & 2 deletions core/formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ class Unparser {
unparse(ast->right, true);

} else if (auto *ast = dynamic_cast<const BuiltinFunction *>(ast_)) {
o << "/* builtin " << ast->name << " */ null";
o << "/* builtin " << ast->body->name << " */ null";

} else if (auto *ast = dynamic_cast<const Conditional *>(ast_)) {
o << "if";
Expand Down Expand Up @@ -1753,7 +1753,7 @@ class FixIndentation {

} else if (auto *ast = dynamic_cast<BuiltinFunction *>(ast_)) {
column += 11; // "/* builtin "
column += ast->name.length();
column += ast->body->name.length();
column += 8; // " */ null"

} else if (auto *ast = dynamic_cast<Conditional *>(ast_)) {
Expand Down
1 change: 1 addition & 0 deletions core/pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ void CompilerPass::visitExpr(AST *&ast_)
VISIT(ast_, AST_ASSERT, Assert);
VISIT(ast_, AST_BINARY, Binary);
VISIT(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction);
VISIT(ast_, AST_BUILTIN_FUNCTION_BODY, BuiltinFunctionBody);
VISIT(ast_, AST_CONDITIONAL, Conditional);
VISIT(ast_, AST_DESUGARED_OBJECT, DesugaredObject);
VISIT(ast_, AST_DOLLAR, Dollar);
Expand Down
2 changes: 2 additions & 0 deletions core/pass.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class CompilerPass {

virtual void visit(BuiltinFunction *) {}

virtual void visit(BuiltinFunctionBody *) {}

virtual void visit(Conditional *ast);

virtual void visit(Dollar *) {}
Expand Down
3 changes: 3 additions & 0 deletions core/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
#ifndef JSONNET_STATE_H
#define JSONNET_STATE_H

#include "ast.h"
namespace jsonnet::internal {
namespace {

Expand Down Expand Up @@ -288,6 +289,8 @@ struct HeapClosure : public HeapEntity {
builtinName(builtin_name)
{
}

bool isBuiltin() const { return !this->body || this->body->type == AST_BUILTIN_FUNCTION_BODY; }
};

/** Stores a simple string on the heap. */
Expand Down
Loading