You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
2.5 KiB
119 lines
2.5 KiB
/* |
|
* Copyright (C) 2023 Riyyi |
|
* |
|
* SPDX-License-Identifier: MIT |
|
*/ |
|
|
|
#include <cstddef> // size_t |
|
#include <memory> // std:static_pointer_cast |
|
|
|
#include "ast.h" |
|
#include "env/macro.h" |
|
#include "forward.h" |
|
#include "util.h" |
|
|
|
namespace blaze { |
|
|
|
// (list 1 2) -> (1 2) |
|
ADD_FUNCTION( |
|
"list", |
|
{ |
|
return makePtr<List>(begin, end); |
|
}); |
|
|
|
// (make-list 4 nil) -> (nil nil nil nil) |
|
ADD_FUNCTION( |
|
"make-list", |
|
{ |
|
CHECK_ARG_COUNT_IS("make-list", SIZE(), 2); |
|
|
|
VALUE_CAST(number, Number, (*begin)); |
|
auto count = static_cast<size_t>(number->number() < 0 ? 0 : number->number()); |
|
auto value = *std::next(begin); |
|
|
|
auto nodes = ValueVector(count); |
|
if (is<Atom>(value.get())) { |
|
auto atom = std::static_pointer_cast<Atom>(value); |
|
for (size_t i = 0; i < count; ++i) { |
|
nodes[i] = makePtr<Atom>(atom); |
|
} |
|
} |
|
// else if (is<Collection>(value.get())) { |
|
// for (size_t i = 0; i < count; ++i) { |
|
// auto nodes = std::static_pointer_cast<Collection>(value)->nodesCopy(); |
|
// if (is<Vector>(value.get())) { |
|
// makePtr<Vector>(nodes); |
|
// continue; |
|
// } |
|
// nodes[i] = makePtr<List>(nodes); |
|
// } |
|
// } |
|
// else if (is<Constant>(value.get())) { |
|
// for (size_t i = 0; i < count; ++i) { |
|
// auto constant = std::static_pointer_cast<Constant>(value); |
|
// nodes[i] = makePtr<Constant>(constant); |
|
// } |
|
// } |
|
|
|
// TODO: |
|
// Atom |
|
// Collection |
|
// Constant |
|
// Function |
|
// HashMap |
|
// Keyword |
|
// Lambda |
|
// List |
|
// Macro |
|
// Number |
|
// String |
|
// Symbol |
|
// Vector |
|
|
|
return makePtr<List>(std::move(nodes)); |
|
}); |
|
|
|
// ----------------------------------------- |
|
|
|
// (vec (list 1 2 3)) |
|
ADD_FUNCTION( |
|
"vec", |
|
{ |
|
CHECK_ARG_COUNT_IS("vec", SIZE(), 1); |
|
|
|
if (is<Vector>(begin->get())) { |
|
return *begin; |
|
} |
|
|
|
VALUE_CAST(collection, Collection, (*begin)); |
|
|
|
return makePtr<Vector>(collection->nodesCopy()); |
|
}); |
|
|
|
// (vector 1 2 3) -> [1 2 3] |
|
ADD_FUNCTION( |
|
"vector", |
|
{ |
|
auto result = makePtr<Vector>(); |
|
|
|
return makePtr<Vector>(begin, end); |
|
}); |
|
|
|
// ----------------------------------------- |
|
|
|
// (hash-map "foo" 5 :bar 10) -> {"foo" 5 :bar 10} |
|
ADD_FUNCTION( |
|
"hash-map", |
|
{ |
|
CHECK_ARG_COUNT_EVEN("hash-map", SIZE()); |
|
|
|
Elements elements; |
|
for (auto it = begin; it != end; std::advance(it, 2)) { |
|
const ValuePtr& value = *(std::next(it)); // temporary instance to get around const |
|
elements.insert_or_assign(HashMap::getKeyString(*it), value); |
|
} |
|
|
|
return makePtr<HashMap>(elements); |
|
}); |
|
|
|
} // namespace blaze
|
|
|