Skip to content

Commit

Permalink
implement array slicing
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedanese committed Feb 17, 2016
1 parent 27ddf2c commit 276038e
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 18 deletions.
7 changes: 4 additions & 3 deletions core/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,11 @@ struct Importstr : public AST {
*/
struct Index : public AST {
AST *target;
AST *index;
AST *first;
AST *second;
const Identifier *id;
Index(const LocationRange &lr, AST *target, AST *index, const Identifier *id)
: AST(lr, AST_INDEX), target(target), index(index), id(id)
Index(const LocationRange &lr, AST *target, AST *first, AST *second, const Identifier *id)
: AST(lr, AST_INDEX), target(target), first(first), second(second), id(id)
{ }
};

Expand Down
35 changes: 27 additions & 8 deletions core/desugaring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class Desugarer {
E,
std(),
str(U"length"),
nullptr,
nullptr),
std::vector<AST*>{v},
false, // trailingComma
Expand Down Expand Up @@ -420,7 +421,7 @@ class Desugarer {
ast->location,
Local::Binds {{
spec.var,
make<Index>(E, var(_l), var(_i[i]), nullptr),
make<Index>(E, var(_l), var(_i[i]), nullptr, nullptr),
}},
in)
)
Expand Down Expand Up @@ -462,15 +463,15 @@ class Desugarer {

switch (ast->op) {
case BOP_PERCENT: {
AST *f_mod = alloc->make<Index>(E, std(), str(U"mod"), nullptr);
AST *f_mod = alloc->make<Index>(E, std(), str(U"mod"), nullptr, nullptr);
std::vector<AST*> args = {ast->left, ast->right};
ast_ = alloc->make<Apply>(ast->location, f_mod, args, false, false);
} break;

case BOP_MANIFEST_UNEQUAL:
invert = true;
case BOP_MANIFEST_EQUAL: {
AST *f_equals = alloc->make<Index>(E, std(), str(U"equals"), nullptr);
AST *f_equals = alloc->make<Index>(E, std(), str(U"equals"), nullptr, nullptr);
std::vector<AST*> args = {ast->left, ast->right};
ast_ = alloc->make<Apply>(ast->location, f_equals, args, false, false);
if (invert)
Expand Down Expand Up @@ -513,11 +514,29 @@ class Desugarer {
} else if (auto *ast = dynamic_cast<Index*>(ast_)) {
desugar(ast->target, obj_level);
if (ast->id != nullptr) {
assert(ast->index == nullptr);
ast->index = str(ast->id->name);
assert(ast->first == nullptr);
ast->first = str(ast->id->name);
ast->id = nullptr;
}
desugar(ast->index, obj_level);
if (ast->second != nullptr) {
ast_ = make<Apply>(
ast->location,
make<Index>(
E,
std(),
str(U"slice"),
nullptr,
nullptr),
std::vector<AST*>{
ast->target,
ast->first,
ast->second,
},
false,
false
);
}
desugar(ast->first, obj_level);

} else if (auto *ast = dynamic_cast<Local*>(ast_)) {
for (auto &bind: ast->binds)
Expand Down Expand Up @@ -611,7 +630,7 @@ class Desugarer {
num << counter++;
binds.emplace_back(
spec.var,
make<Index>(E, var(_arr), make<LiteralNumber>(E, num.str()), nullptr));
make<Index>(E, var(_arr), make<LiteralNumber>(E, num.str()), nullptr, nullptr));
arr_e.push_back(var(spec.var));
}
}
Expand All @@ -623,7 +642,7 @@ class Desugarer {
desugar(arr, obj_level);
ast_ = make<ObjectComprehensionSimple>(
ast->location,
make<Index>(E, var(_arr), zero, nullptr),
make<Index>(E, var(_arr), zero, nullptr, nullptr),
make<Local>(
ast->location,
binds,
Expand Down
13 changes: 9 additions & 4 deletions core/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ static std::string unparse(const AST *ast_, int precedence)
if (ast->id != nullptr) {
ss << "." << unparse(ast->id);
} else {
ss << "[" << unparse(ast->index, MAX_PRECEDENCE) << "]";
ss << "[" << unparse(ast->first, MAX_PRECEDENCE) << "]";
}

} else if (auto *ast = dynamic_cast<const Local*>(ast_)) {
Expand Down Expand Up @@ -1186,14 +1186,19 @@ namespace {

Token op = pop();
if (op.kind == Token::BRACKET_L) {
AST *index = parse(MAX_PRECEDENCE);
AST *first = parse(MAX_PRECEDENCE);
AST *second = nullptr;
if (peek().data == ":") {
pop();
second = parse(MAX_PRECEDENCE);
}
Token end = popExpect(Token::BRACKET_R);
lhs = alloc->make<Index>(span(begin, end), lhs, index, nullptr);
lhs = alloc->make<Index>(span(begin, end), lhs, first, second, nullptr);

} else if (op.kind == Token::DOT) {
Token field_id = popExpect(Token::IDENTIFIER);
const Identifier *id = alloc->makeIdentifier(field_id.data32());
lhs = alloc->make<Index>(span(begin, field_id), lhs, nullptr, id);
lhs = alloc->make<Index>(span(begin, field_id), lhs, nullptr, nullptr, id);

} else if (op.kind == Token::PAREN_L) {
std::vector<AST*> args;
Expand Down
2 changes: 1 addition & 1 deletion core/static_analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static IdSet static_analysis(AST *ast_, bool in_object, const IdSet &vars)

} else if (auto *ast = dynamic_cast<const Index*>(ast_)) {
append(r, static_analysis(ast->target, in_object, vars));
append(r, static_analysis(ast->index, in_object, vars));
append(r, static_analysis(ast->first, in_object, vars));

} else if (auto *ast = dynamic_cast<const Local*>(ast_)) {
IdSet ast_vars;
Expand Down
4 changes: 2 additions & 2 deletions core/vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@ namespace {
}
}
}
ast_ = ast.index;
ast_ = ast.first;
goto recurse;
} break;

Expand All @@ -1970,7 +1970,7 @@ namespace {
stack.pop();
Frame &f2 = stack.top();
const auto &ast = *static_cast<const Index*>(f2.ast);
ast_ = ast.index;
ast_ = ast.first;
goto recurse;
}
auto *thunk = f.thunks[f.elementId++];
Expand Down
3 changes: 3 additions & 0 deletions stdlib/std.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ limitations under the License.
range(from, to)::
std.makeArray(to - from + 1, function(i) i + from),

slice(arr, from, to)::
std.makeArray(to - from, function(i) arr[i + from]),

count(arr, x):: std.length(std.filter(function(v) v==x, arr)),

mod(a, b)::
Expand Down

0 comments on commit 276038e

Please sign in to comment.