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 == "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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
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];
|
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;
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user