Type assertion and initialization

This commit is contained in:
2025-10-04 20:57:16 +10:00
parent 0057d73215
commit b628c00f9e
7 changed files with 94 additions and 10 deletions

View File

@@ -21,6 +21,7 @@ InstructionType strToInstructionType(std::string in) {
else if (in == "split") return InstructionType::Split; else if (in == "split") return InstructionType::Split;
else if (in == "file") return InstructionType::File; else if (in == "file") return InstructionType::File;
else if (in == "struct") return InstructionType::Struct; else if (in == "struct") return InstructionType::Struct;
else if (in == "assert") return InstructionType::Assert;
else return InstructionType::Variable; else return InstructionType::Variable;
} }
@@ -70,6 +71,12 @@ Instruction::Instruction(std::vector<Value> toks) {
Value::Value(std::string stringval) { Value::Value(std::string stringval) {
// This constructor will attempt to parse the string into the most specific type possible. // 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() == '"') { if (stringval.length() >= 2 && stringval.front() == '"' && stringval.back() == '"') {
valtype = ValueType::String; valtype = ValueType::String;
string_val = stringval.substr(1, stringval.length() - 2); 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(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(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) { if (other.processed) {
processed = std::make_unique<Instruction>(*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(std::string in) : key(in.substr(1)) {}
Varname::Varname() : key("") {} Varname::Varname() : key("") {}
@@ -143,6 +150,7 @@ Value& Value::operator=(const Value& other) {
instructionGroup = other.instructionGroup; instructionGroup = other.instructionGroup;
list = other.list; list = other.list;
map = other.map; map = other.map;
type_placeholder_name = other.type_placeholder_name;
fn_val = other.fn_val; fn_val = other.fn_val;
if (other.processed) { if (other.processed) {
processed = std::make_unique<Instruction>(*other.processed); processed = std::make_unique<Instruction>(*other.processed);

View File

@@ -6,11 +6,11 @@
#include <map> #include <map>
enum class InstructionType { 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 { 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; struct Instruction;
@@ -37,6 +37,7 @@ struct Value {
InstructionGroup instructionGroup; InstructionGroup instructionGroup;
std::vector<Value> list; std::vector<Value> list;
std::map<std::string, Value> map; std::map<std::string, Value> map;
std::string type_placeholder_name;
bool is_return = false; bool is_return = false;
std::string toString() const; std::string toString() const;
Varname varName = Varname(); Varname varName = Varname();

View File

@@ -18,6 +18,7 @@
#include "../modules/split/split.h" #include "../modules/split/split.h"
#include "../modules/concat/concat.h" #include "../modules/concat/concat.h"
#include "../modules/file/file.h" #include "../modules/file/file.h"
#include "../modules/assert/assert.h"
// Forward declaration for mutual recursion // Forward declaration for mutual recursion
Value evaluate(Value val); Value evaluate(Value val);
@@ -39,6 +40,9 @@ Value execute(Instruction inst) {
if (inst.instruction == InstructionType::Struct) { if (inst.instruction == InstructionType::Struct) {
return modules::structdef(inst.args); return modules::structdef(inst.args);
} }
if (inst.instruction == InstructionType::Assert) {
return modules::assert(inst.args);
}
if (inst.instruction == InstructionType::Variable) { if (inst.instruction == InstructionType::Variable) {
auto& args = inst.args; auto& args = inst.args;

View 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();
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include "../../defs/defs.h"
#include <vector>
namespace modules {
Value assert(std::vector<Value> args);
}

View File

@@ -17,6 +17,20 @@ Value evaluate(Value val) {
return (*it)[val.string_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; return val;
} }

View File

@@ -1,10 +1,10 @@
struct Data { struct Data {
status = <Bool> status = <Int>
moreCrap = ["dingus", 32] moreCrap = ["dingus", 32]
fun init status moreCrap { fun init status moreCrap {
#assert $status is <Bool> assert $status is <Int>
#assert $morecrap is <List> assert $moreCrap is <List>
println "Initing!" println "Initing!"
self status = $status self status = $status
self moreCrap = $moreCrap 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 myData testMemberFn