Fixed baking the right integer types into values from #ctce, added the rest of the integer type literals (10ul, etc), fixed/added struct padding/alignment in interpreter

This commit is contained in:
Nathan Braswell
2016-07-09 00:45:40 -07:00
parent dc5fe39083
commit ddd250e7f3
7 changed files with 204 additions and 43 deletions

View File

@@ -554,13 +554,28 @@ obj ast_transformation (Object) {
break
}
}
if (contains_dot)
if (value_str[value_str.length()-1] == 'f')
if (contains_dot) {
if (value_str.last() == 'f')
value_type = type_ptr(base_type::floating()) //value_type = type_ptr(base_type::floating())
else
value_type = type_ptr(base_type::double_precision()) //value_type = type_ptr(base_type::floating())
else
value_type = type_ptr(base_type::integer())
} else {
var chop = 0
if (value_str.length() > 2) {
var s = value_str.slice(-3,-1)
if (s == "uc") { chop = 2; value_type = type_ptr(base_type::ucharacter()); }
else if (s == "us") { chop = 2; value_type = type_ptr(base_type::ushort_int()); }
else if (s == "ul") { chop = 2; value_type = type_ptr(base_type::ulong_int()); }
}
if (chop == 0) {
if (value_str.last() == 'c') { chop = 1; value_type = type_ptr(base_type::character()); }
else if (value_str.last() == 's') { chop = 1; value_type = type_ptr(base_type::short_int()); }
else if (value_str.last() == 'u') { chop = 1; value_type = type_ptr(base_type::uinteger()); }
else if (value_str.last() == 'l') { chop = 1; value_type = type_ptr(base_type::long_int()); }
}
if (chop == 0) value_type = type_ptr(base_type::integer())
value_str = value_str.slice(0, -1-chop)
}
}
return ast_value_ptr(value_str, value_type)
}

View File

@@ -63,6 +63,7 @@ fun raw_to_value(data:double): value
fun wrap_value(val: *ast_node): value {
var value_str = val->value.string_value
var value_type = val->value.value_type
if (value_str[0] == '"') { // " // Comment hack for emacs now
var to_ret = string()
// triple quoted strings
@@ -113,8 +114,18 @@ fun wrap_value(val: *ast_node): value {
return value::double_precision(string_to_double(value_str.slice(0,-2)))
else
return value::double_precision(string_to_double(value_str))
else
return value::integer(string_to_int(value_str))
else {
match(value_type->base) {
base_type::character() return value::character(string_to_num<char>(value_str))
base_type::ucharacter() return value::ucharacter(string_to_num<uchar>(value_str))
base_type::short_int() return value::short_int(string_to_num<short>(value_str))
base_type::ushort_int() return value::ushort_int(string_to_num<ushort>(value_str))
base_type::integer() return value::integer(string_to_num<int>(value_str))
base_type::uinteger() return value::uinteger(string_to_num<uint>(value_str))
base_type::long_int() return value::long_int(string_to_num<long>(value_str))
base_type::ulong_int() return value::ulong_int(string_to_num<ulong>(value_str))
}
}
}
error("Could not wrap value")
return value::void_nothing()
@@ -484,47 +495,63 @@ fun cast_value_second_half<T>(v: value): value {
}
error("Illegal type to cast cast from")
}
fun type_size(t: *type): ulong {
fun type_size(t: *type): ulong
return type_size_and_alignment(t).first
fun type_size_and_alignment(t: *type): pair<ulong,ulong> {
if (t->indirection)
return #sizeof<*void>
return make_pair(#sizeof<*void>, #sizeof<*void>)
match (t->base) {
base_type::object() {
var size: ulong = 0
var total_size: ulong = 0
var max_size: ulong = 0
var max_align: ulong = 0
t->type_def->type_def.variables.for_each(fun(i: *ast_node) {
var individual_size = type_size(i->declaration_statement.identifier->identifier.type)
if (t->type_def->type_def.is_union) {
size = max(size, individual_size)
} else {
size += individual_size
}
var individual = type_size_and_alignment(i->declaration_statement.identifier->identifier.type)
max_size = max(max_size, individual.first)
max_align = max(max_align, individual.second)
// increase total size by the individual size + padding to get alignment
var padding = 0
if (individual.second != 0)
padding = (individual.second - (total_size % individual.second)) % individual.second
total_size += individual.first + padding
})
return size
if (t->type_def->type_def.is_union)
total_size = max_size
// pad the end so that consecutive objects in memory are aligned
if (max_align != 0)
total_size += (max_align - (total_size % max_align)) % max_align
return make_pair(total_size, max_align)
}
base_type::function() return #sizeof<pair<*ast_node,*map<*ast_node,value>>>
base_type::boolean() return #sizeof<bool>
base_type::character() return #sizeof<char>
base_type::ucharacter() return #sizeof<uchar>
base_type::short_int() return #sizeof<short>
base_type::ushort_int() return #sizeof<ushort>
base_type::integer() return #sizeof<int>
base_type::uinteger() return #sizeof<uint>
base_type::long_int() return #sizeof<long>
base_type::ulong_int() return #sizeof<ulong>
base_type::floating() return #sizeof<float>
base_type::double_precision() return #sizeof<double>
base_type::function() return make_pair(#sizeof<pair<*ast_node,*map<*ast_node,value>>>, #sizeof<*void>)
base_type::boolean() return make_pair(#sizeof<bool>, #sizeof<bool>)
base_type::character() return make_pair(#sizeof<char>, #sizeof<char>)
base_type::ucharacter() return make_pair(#sizeof<uchar>, #sizeof<uchar>)
base_type::short_int() return make_pair(#sizeof<short>, #sizeof<short>)
base_type::ushort_int() return make_pair(#sizeof<ushort>, #sizeof<ushort>)
base_type::integer() return make_pair(#sizeof<int>, #sizeof<int>)
base_type::uinteger() return make_pair(#sizeof<uint>, #sizeof<uint>)
base_type::long_int() return make_pair(#sizeof<long>, #sizeof<long>)
base_type::ulong_int() return make_pair(#sizeof<ulong>, #sizeof<ulong>)
base_type::floating() return make_pair(#sizeof<float>, #sizeof<float>)
base_type::double_precision() return make_pair(#sizeof<double>, #sizeof<double>)
}
error(string("Invalid type for type_size: ") + t->to_string())
}
fun offset_into_struct(struct_type: *type, ident: *ast_node): ulong {
var size: ulong = 0
var offset: ulong = 0
if (struct_type->type_def->type_def.is_union)
return size
for (var i = 0; i < struct_type->type_def->type_def.variables.size; i++;)
return offset
for (var i = 0; i < struct_type->type_def->type_def.variables.size; i++;) {
var size_and_align = type_size_and_alignment(struct_type->type_def->type_def.variables[i]->declaration_statement.identifier->identifier.type)
var align = size_and_align.second
if (align != 0)
offset += (align - (offset % align)) % align
if (struct_type->type_def->type_def.variables[i]->declaration_statement.identifier == ident)
break
else
size += type_size(struct_type->type_def->type_def.variables[i]->declaration_statement.identifier->identifier.type)
return size
offset += size_and_align.first
}
return offset
}
// to dereference, we basically take the pointer's value (maybe going through a variable to get it)
// and re-wrap it up into a variable value (so it can be assigned to, etc)

View File

@@ -37,14 +37,14 @@ fun to_string(in: ulong): string
fun to_string<T>(in: *T): string
return string("ptr:<") + to_string_num((in) cast ulong) + ">"
fun string_to_int(it: string): int {
fun string_to_num<T>(it: string): T {
var is_negative = false
if (it[0] == '-') {
is_negative = true
it = it.slice(1,-1)
}
var result = 0
var power = 1
var result:T = 0
var power:T = 1
while (it.length()) {
result += power * (it.last() - '0')
it = it.slice(0,-2)
@@ -58,7 +58,7 @@ fun string_to_double(it: string): double {
var parts = it.split('.')
var divisor = 1
for (var i = 0; i < parts[1].length(); i++;) divisor *= 10
return string_to_int(parts[0]) + (string_to_int(parts[1])) cast double / divisor
return string_to_num<long>(parts[0]) + (string_to_num<long>(parts[1])) cast double / divisor
}
fun to_string_num<T>(in: T): string {