Type assertion and initialization
This commit is contained in:
@@ -21,6 +21,7 @@ InstructionType strToInstructionType(std::string in) {
|
||||
else if (in == "split") return InstructionType::Split;
|
||||
else if (in == "file") return InstructionType::File;
|
||||
else if (in == "struct") return InstructionType::Struct;
|
||||
else if (in == "assert") return InstructionType::Assert;
|
||||
else return InstructionType::Variable;
|
||||
}
|
||||
|
||||
@@ -70,6 +71,12 @@ Instruction::Instruction(std::vector<Value> toks) {
|
||||
|
||||
Value::Value(std::string stringval) {
|
||||
// This constructor will attempt to parse the string into the most specific type possible.
|
||||
if (stringval.length() > 2 && stringval.front() == '<' && stringval.back() == '>') {
|
||||
valtype = ValueType::TypePlaceholder;
|
||||
type_placeholder_name = stringval.substr(1, stringval.length() - 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stringval.length() >= 2 && stringval.front() == '"' && stringval.back() == '"') {
|
||||
valtype = ValueType::String;
|
||||
string_val = stringval.substr(1, stringval.length() - 2);
|
||||
@@ -120,16 +127,16 @@ Value::Value(std::vector<Value> listval) : valtype(ValueType::List), list(std::m
|
||||
|
||||
Value::Value(std::map<std::string, Value> mapval) : valtype(ValueType::Map), map(std::move(mapval)) {}
|
||||
|
||||
Value::Value(Varname var) : valtype(ValueType::Variable), varName(var) {}
|
||||
|
||||
Value::Value(Function func) : fn_val(func) {};
|
||||
|
||||
Value::Value(const Value& other) : valtype(other.valtype), string_val(other.string_val), int_val(other.int_val), double_val(other.double_val), instructionGroup(other.instructionGroup), list(other.list), map(other.map), varName(other.varName), fn_val(other.fn_val) {
|
||||
Value::Value(const Value& other) : valtype(other.valtype), string_val(other.string_val), int_val(other.int_val), double_val(other.double_val), instructionGroup(other.instructionGroup), list(other.list), map(other.map), type_placeholder_name(other.type_placeholder_name), varName(other.varName), fn_val(other.fn_val) {
|
||||
if (other.processed) {
|
||||
processed = std::make_unique<Instruction>(*other.processed);
|
||||
}
|
||||
}
|
||||
|
||||
Value::Value(Varname varname) : valtype(ValueType::Variable), varName(varname) {}
|
||||
|
||||
Varname::Varname(std::string in) : key(in.substr(1)) {}
|
||||
Varname::Varname() : key("") {}
|
||||
|
||||
@@ -143,6 +150,7 @@ Value& Value::operator=(const Value& other) {
|
||||
instructionGroup = other.instructionGroup;
|
||||
list = other.list;
|
||||
map = other.map;
|
||||
type_placeholder_name = other.type_placeholder_name;
|
||||
fn_val = other.fn_val;
|
||||
if (other.processed) {
|
||||
processed = std::make_unique<Instruction>(*other.processed);
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#include <map>
|
||||
|
||||
enum class InstructionType {
|
||||
None, Print, Println, Math, Let, Variable, Exit, If, While, Input, Compare, Function, Struct, Return, Concat, Split, File
|
||||
None, Print, Println, Math, Let, Variable, Exit, If, While, Input, Compare, Function, Struct, Return, Concat, Split, File, Assert
|
||||
};
|
||||
|
||||
enum class ValueType {
|
||||
Processed, Variable, InstructionGroup, List, Map, String, Int, Double, Identifier, Custom
|
||||
Processed, Variable, InstructionGroup, List, Map, String, Int, Double, Identifier, Custom, TypePlaceholder
|
||||
};
|
||||
|
||||
struct Instruction;
|
||||
@@ -37,6 +37,7 @@ struct Value {
|
||||
InstructionGroup instructionGroup;
|
||||
std::vector<Value> list;
|
||||
std::map<std::string, Value> map;
|
||||
std::string type_placeholder_name;
|
||||
bool is_return = false;
|
||||
std::string toString() const;
|
||||
Varname varName = Varname();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "../modules/split/split.h"
|
||||
#include "../modules/concat/concat.h"
|
||||
#include "../modules/file/file.h"
|
||||
#include "../modules/assert/assert.h"
|
||||
|
||||
// Forward declaration for mutual recursion
|
||||
Value evaluate(Value val);
|
||||
@@ -39,6 +40,9 @@ Value execute(Instruction inst) {
|
||||
if (inst.instruction == InstructionType::Struct) {
|
||||
return modules::structdef(inst.args);
|
||||
}
|
||||
if (inst.instruction == InstructionType::Assert) {
|
||||
return modules::assert(inst.args);
|
||||
}
|
||||
if (inst.instruction == InstructionType::Variable) {
|
||||
auto& args = inst.args;
|
||||
|
||||
|
||||
49
src/modules/assert/assert.cpp
Normal file
49
src/modules/assert/assert.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "assert.h"
|
||||
#include "../../error/error.h"
|
||||
#include "../../data/data.h"
|
||||
#include "../../utils/evaluate/evaluate.h"
|
||||
|
||||
Value modules::assert(std::vector<Value> args) {
|
||||
if (args.size() != 3 || args[1].valtype != ValueType::Identifier || args[1].string_val != "is") {
|
||||
error("Syntax error: assert requires <value> is <type>");
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value val = evaluate(args[0]);
|
||||
Value& type = args[2];
|
||||
|
||||
if (type.valtype != ValueType::TypePlaceholder) {
|
||||
error("Syntax error: assert expects a type placeholder (e.g., <String>)");
|
||||
return Value();
|
||||
}
|
||||
|
||||
std::string type_name = type.type_placeholder_name;
|
||||
bool condition = false;
|
||||
|
||||
if (type_name == "Any") {
|
||||
condition = true;
|
||||
} else if (type_name == "String") {
|
||||
condition = (val.valtype == ValueType::String);
|
||||
} else if (type_name == "List") {
|
||||
condition = (val.valtype == ValueType::List);
|
||||
} else if (type_name == "Int") {
|
||||
condition = (val.valtype == ValueType::Int);
|
||||
} else if (type_name == "Double") {
|
||||
condition = (val.valtype == ValueType::Double);
|
||||
} else if (type_name == "Bool") {
|
||||
condition = (val.valtype == ValueType::String && (val.string_val == "true" || val.string_val == "false"));
|
||||
} else {
|
||||
// Check for user-defined struct types
|
||||
if (data::structs.count(type_name)) {
|
||||
condition = (val.valtype == ValueType::Map && val.map.count("__name__") && val.map.at("__name__").string_val == type_name);
|
||||
} else {
|
||||
error("Unknown type for assert: " + type_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!condition) {
|
||||
error("Assertion failed: value is not of type " + type_name);
|
||||
}
|
||||
|
||||
return Value();
|
||||
}
|
||||
8
src/modules/assert/assert.h
Normal file
8
src/modules/assert/assert.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../defs/defs.h"
|
||||
#include <vector>
|
||||
|
||||
namespace modules {
|
||||
Value assert(std::vector<Value> args);
|
||||
}
|
||||
@@ -17,6 +17,20 @@ Value evaluate(Value val) {
|
||||
return (*it)[val.string_val];
|
||||
}
|
||||
}
|
||||
} else if (val.valtype == ValueType::TypePlaceholder) {
|
||||
if (val.type_placeholder_name == "String") {
|
||||
return Value("");
|
||||
} else if (val.type_placeholder_name == "List") {
|
||||
return Value(std::vector<Value>());
|
||||
} else if (val.type_placeholder_name == "Int") {
|
||||
return Value((long long)0);
|
||||
} else if (val.type_placeholder_name == "Double") {
|
||||
return Value((double)0.0);
|
||||
} else if (val.type_placeholder_name == "Bool") {
|
||||
return Value("false");
|
||||
} else if (val.type_placeholder_name == "Any") {
|
||||
return Value(""); // Default for Any is an empty string
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
struct Data {
|
||||
status = <Bool>
|
||||
status = <Int>
|
||||
moreCrap = ["dingus", 32]
|
||||
|
||||
fun init status moreCrap {
|
||||
#assert $status is <Bool>
|
||||
#assert $morecrap is <List>
|
||||
assert $status is <Int>
|
||||
assert $moreCrap is <List>
|
||||
println "Initing!"
|
||||
self status = $status
|
||||
self moreCrap = $moreCrap
|
||||
@@ -20,7 +20,7 @@ struct Data {
|
||||
}
|
||||
}
|
||||
|
||||
let myData = (Data "true" ["dingus", "dongus", "mingus", "mongus"])
|
||||
let myData = (Data 0 ["dingus", "dongus", "mingus", "mongus"])
|
||||
|
||||
myData testMemberFn
|
||||
|
||||
|
||||
Reference in New Issue
Block a user