rm type inference
This commit is contained in:
parent
cbb37dd4cd
commit
d34efd9626
|
|
@ -1,38 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "jinja-value.h"
|
|
||||||
|
|
||||||
namespace jinja {
|
|
||||||
|
|
||||||
struct value_t;
|
|
||||||
using value = std::shared_ptr<value_t>;
|
|
||||||
|
|
||||||
// this is used as a hint for chat parsing
|
|
||||||
// it is not a 1-to-1 mapping to value_t derived types
|
|
||||||
enum class inferred_type {
|
|
||||||
numeric, // int, float
|
|
||||||
string,
|
|
||||||
boolean,
|
|
||||||
array,
|
|
||||||
object,
|
|
||||||
optional, // null, undefined
|
|
||||||
unknown,
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::string inferred_type_to_string(inferred_type type) {
|
|
||||||
switch (type) {
|
|
||||||
case inferred_type::numeric: return "numeric";
|
|
||||||
case inferred_type::string: return "string";
|
|
||||||
case inferred_type::boolean: return "boolean";
|
|
||||||
case inferred_type::array: return "array";
|
|
||||||
case inferred_type::object: return "object";
|
|
||||||
case inferred_type::optional: return "optional";
|
|
||||||
case inferred_type::unknown: return "unknown";
|
|
||||||
default: return "invalid";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace jinja
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "jinja-string.h"
|
#include "jinja-string.h"
|
||||||
#include "jinja-type-infer.h"
|
|
||||||
|
|
||||||
namespace jinja {
|
namespace jinja {
|
||||||
|
|
||||||
|
|
@ -108,10 +107,6 @@ struct value_t {
|
||||||
|
|
||||||
func_handler val_func;
|
func_handler val_func;
|
||||||
|
|
||||||
// for type inference
|
|
||||||
std::set<inferred_type> inf_types;
|
|
||||||
std::vector<value> inf_vals;
|
|
||||||
|
|
||||||
value_t() = default;
|
value_t() = default;
|
||||||
value_t(const value_t &) = default;
|
value_t(const value_t &) = default;
|
||||||
virtual ~value_t() = default;
|
virtual ~value_t() = default;
|
||||||
|
|
@ -343,23 +338,5 @@ using value_kwarg = std::shared_ptr<value_kwarg_t>;
|
||||||
|
|
||||||
const func_builtins & global_builtins();
|
const func_builtins & global_builtins();
|
||||||
|
|
||||||
static inferred_type value_to_inferred_type(const value & val) {
|
|
||||||
if (is_val<value_int>(val) || is_val<value_float>(val)) {
|
|
||||||
return inferred_type::numeric;
|
|
||||||
} else if (is_val<value_string>(val)) {
|
|
||||||
return inferred_type::string;
|
|
||||||
} else if (is_val<value_bool>(val)) {
|
|
||||||
return inferred_type::boolean;
|
|
||||||
} else if (is_val<value_array>(val)) {
|
|
||||||
return inferred_type::array;
|
|
||||||
} else if (is_val<value_object>(val)) {
|
|
||||||
return inferred_type::object;
|
|
||||||
} else if (is_val<value_null>(val) || is_val<value_undefined>(val)) {
|
|
||||||
return inferred_type::optional;
|
|
||||||
} else {
|
|
||||||
return inferred_type::unknown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace jinja
|
} // namespace jinja
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,6 @@ value binary_expression::execute_impl(context & ctx) {
|
||||||
value right_val = right->execute(ctx);
|
value right_val = right->execute(ctx);
|
||||||
JJ_DEBUG("Executing binary expression %s '%s' %s", left_val->type().c_str(), op.value.c_str(), right_val->type().c_str());
|
JJ_DEBUG("Executing binary expression %s '%s' %s", left_val->type().c_str(), op.value.c_str(), right_val->type().c_str());
|
||||||
if (op.value == "==") {
|
if (op.value == "==") {
|
||||||
ctx.mark_known_type(left_val, right_val);
|
|
||||||
ctx.mark_known_type(right_val, left_val);
|
|
||||||
return mk_val<value_bool>(value_compare(left_val, right_val));
|
return mk_val<value_bool>(value_compare(left_val, right_val));
|
||||||
} else if (op.value == "!=") {
|
} else if (op.value == "!=") {
|
||||||
return mk_val<value_bool>(!value_compare(left_val, right_val));
|
return mk_val<value_bool>(!value_compare(left_val, right_val));
|
||||||
|
|
@ -318,13 +316,6 @@ value test_expression::execute_impl(context & ctx) {
|
||||||
args.args.push_back(input);
|
args.args.push_back(input);
|
||||||
auto res = it->second(args);
|
auto res = it->second(args);
|
||||||
|
|
||||||
// hack: allow type inference
|
|
||||||
if (test_id == "defined" || test_id == "undefined" || test_id == "none") {
|
|
||||||
ctx.mark_known_type(input, inferred_type::optional);
|
|
||||||
} else if (test_id == "string") {
|
|
||||||
ctx.mark_known_type(input, inferred_type::string);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (negate) {
|
if (negate) {
|
||||||
return mk_val<value_bool>(!res->as_bool());
|
return mk_val<value_bool>(!res->as_bool());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -354,9 +345,6 @@ value unary_expression::execute_impl(context & ctx) {
|
||||||
value if_statement::execute_impl(context & ctx) {
|
value if_statement::execute_impl(context & ctx) {
|
||||||
value test_val = test->execute(ctx);
|
value test_val = test->execute(ctx);
|
||||||
|
|
||||||
ctx.mark_known_type(test_val, inferred_type::boolean);
|
|
||||||
ctx.mark_known_type(test_val, inferred_type::optional);
|
|
||||||
|
|
||||||
auto out = mk_val<value_array>();
|
auto out = mk_val<value_array>();
|
||||||
if (test_val->as_bool()) {
|
if (test_val->as_bool()) {
|
||||||
for (auto & stmt : body) {
|
for (auto & stmt : body) {
|
||||||
|
|
@ -399,9 +387,6 @@ value for_statement::execute_impl(context & ctx) {
|
||||||
iterable_val = mk_val<value_array>();
|
iterable_val = mk_val<value_array>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.mark_known_type(iterable_val, inferred_type::array);
|
|
||||||
ctx.mark_known_type(iterable_val, inferred_type::object);
|
|
||||||
|
|
||||||
if (!is_val<value_array>(iterable_val) && !is_val<value_object>(iterable_val)) {
|
if (!is_val<value_array>(iterable_val) && !is_val<value_object>(iterable_val)) {
|
||||||
throw std::runtime_error("Expected iterable or object type in for loop: got " + iterable_val->type());
|
throw std::runtime_error("Expected iterable or object type in for loop: got " + iterable_val->type());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,46 +78,10 @@ struct context {
|
||||||
|
|
||||||
void set_val(const std::string & name, const value & val) {
|
void set_val(const std::string & name, const value & val) {
|
||||||
global->insert(name, val);
|
global->insert(name, val);
|
||||||
set_flattened_global_recursively(name, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mark_known_type(value & val, inferred_type type) {
|
|
||||||
val->inf_types.insert(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mark_known_type(value & val, value & known_val) {
|
|
||||||
mark_known_type(val, value_to_inferred_type(known_val));
|
|
||||||
val->inf_vals.push_back(known_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FOR TESTING ONLY
|
|
||||||
const value_object & get_global_object() const {
|
|
||||||
return global;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
value_object global;
|
value_object global;
|
||||||
|
|
||||||
public:
|
|
||||||
std::map<std::string, value> flatten_globals; // for debugging
|
|
||||||
void set_flattened_global_recursively(std::string path, const value & val) {
|
|
||||||
flatten_globals[path] = val;
|
|
||||||
if (is_val<value_object>(val)) {
|
|
||||||
auto & obj = val->as_object();
|
|
||||||
for (const auto & pair : obj) {
|
|
||||||
std::string child_path = path + "." + pair.first;
|
|
||||||
flatten_globals[child_path] = pair.second;
|
|
||||||
set_flattened_global_recursively(child_path, pair.second);
|
|
||||||
}
|
|
||||||
} else if (is_val<value_array>(val)) {
|
|
||||||
auto & arr = val->as_array();
|
|
||||||
for (size_t i = 0; i < arr.size(); ++i) {
|
|
||||||
std::string idx_path = path + "[" + std::to_string(i) + "]";
|
|
||||||
flatten_globals[idx_path] = arr[i];
|
|
||||||
set_flattened_global_recursively(idx_path, arr[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
#include "jinja/jinja-parser.h"
|
#include "jinja/jinja-parser.h"
|
||||||
#include "jinja/jinja-lexer.h"
|
#include "jinja/jinja-lexer.h"
|
||||||
#include "jinja/jinja-type-infer.h"
|
|
||||||
|
|
||||||
void run_multiple();
|
void run_multiple();
|
||||||
void run_single(std::string contents);
|
void run_single(std::string contents);
|
||||||
|
|
@ -165,22 +164,4 @@ void run_single(std::string contents) {
|
||||||
for (const auto & part : parts.get()->val_str.parts) {
|
for (const auto & part : parts.get()->val_str.parts) {
|
||||||
std::cout << (part.is_input ? "DATA" : "TMPL") << ": " << part.val << "\n";
|
std::cout << (part.is_input ? "DATA" : "TMPL") << ": " << part.val << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "\n=== TYPES ===\n";
|
|
||||||
auto & global_obj = ctx.flatten_globals;
|
|
||||||
for (const auto & pair : global_obj) {
|
|
||||||
std::string name = pair.first;
|
|
||||||
std::string inf_types;
|
|
||||||
for (const auto & t : pair.second->inf_types) {
|
|
||||||
inf_types += inferred_type_to_string(t) + " ";
|
|
||||||
}
|
|
||||||
if (inf_types.empty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::string inf_vals;
|
|
||||||
for (const auto & v : pair.second->inf_vals) {
|
|
||||||
inf_vals += v->as_string().str() + " ; ";
|
|
||||||
}
|
|
||||||
printf("Var: %-20s | Types: %-10s | Vals: %s\n", name.c_str(), inf_types.c_str(), inf_vals.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue