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

@@ -139,9 +139,8 @@ assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS
# if it's being assigned to, we allow type inferencing
declaration_statement = "var" WS identifier WS "=" WS boolean_expression | "var" WS identifier WS dec_type WS "=" WS boolean_expression | "var" WS identifier WS dec_type | "ext" WS "var" WS identifier WS dec_type | "var" WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" WS dec_type ;
hexadecimal = "0x([0-9]|[a-f])+" ;
integer = numeric | hexadecimal ;
floating_literal = numeric "." float_end ;
float_end = "[0-9]+" | "[0-9]+f" | "[0-9]+d" ;
integer = "[0-9]+u?(c|s|l)?" | hexadecimal ;
floating_literal = "[0-9]+.[0-9]+(f|d)?" ;
bool = "true" | "false" ;
character = "'(`|[0-9]|-|=|(\\t)|[a-z]|\[|]|(\\\\)|;|(\\')|(\\n)|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|\"|<|>|\?| |(\\0))'" ;
@@ -149,7 +148,6 @@ keywords_also_identifiers = "obj" | "def" | "fun" | "var" | "ref" | "adt" | "cas
alpha_alphanumeric = "([a-z]|[A-Z]|_)([a-z]|[A-Z]|_|[0-9])*" ;
augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ;
numeric = "[0-9]+" ;
# note the hacks around \things. Hmm, I feel like it actually shouldn't be like this. Added \\\* because I want to come back later
string = triple_quoted_string | "\"([#-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\\*)|(\\0)|
|[ -!]|(\\\"))*\"" ;

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 {

View File

@@ -1,3 +1,8 @@
=====During CTCE!=====
3
hello, world
From Shell
@@ -12,3 +17,37 @@ From Shell
From Shell
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true

View File

@@ -3,6 +3,53 @@ import os: *
import string: *
import ast_nodes: *
obj first {
var p1: *char
var p2: char
var p3: int
}
obj second {
var p1: *char
var p2: char
var p3: short
}
obj third {
var p1: *char
var p2: long
var p3: char
}
obj fourth {
var p1: char
var p2: *char
var p3: long
}
obj fifth {
var p1: *char
var p2: char
}
obj sixth {
var p1: *char
var p2: char
var p3: long
}
obj seventh {
var p1: char
var p2: *char
var p3: long
}
obj eigth {
var p1: short
var p2: char
}
obj ninth {
var p1: *char
var p2: short
}
obj tenth {
var p1: char
var p2: ninth
}
fun compare_sizes<T>() {
var a = #sizeof<T>
var b = #ctce(#sizeof<T>)
@@ -22,7 +69,42 @@ fun main(): int {
return it.toCharArray()
}()))
}
compare_sizes<first>()
compare_sizes<second>()
compare_sizes<third>()
compare_sizes<fourth>()
compare_sizes<fifth>()
compare_sizes<sixth>()
compare_sizes<seventh>()
compare_sizes<eigth>()
compare_sizes<ninth>()
compare_sizes<tenth>()
compare_sizes<string>()
compare_sizes<ast_node>()
compare_sizes<translation_unit>()
compare_sizes<import>()
compare_sizes<identifier>()
compare_sizes<type_def>()
compare_sizes<adt_def>()
compare_sizes<function>()
compare_sizes<template>()
compare_sizes<code_block>()
compare_sizes<if_statement>()
compare_sizes<match_statement>()
compare_sizes<case_statement>()
compare_sizes<while_loop>()
compare_sizes<for_loop>()
compare_sizes<return_statement>()
compare_sizes<branching_statement>()
compare_sizes<defer_statement>()
compare_sizes<assignment_statement>()
compare_sizes<declaration_statement>()
compare_sizes<if_comp>()
compare_sizes<simple_passthrough>()
compare_sizes<function_call>()
compare_sizes<compiler_intrinsic>()
compare_sizes<cast>()
compare_sizes<value>()
return 0
}

View File

@@ -27,10 +27,10 @@ fun main(argc: int, argv: **char): int {
for (var i = 1; i < argc; i++;) {
var test_name = string(argv[i])
println(string("Doing test for ") + test_name)
if (system(kraken_path + " " + test_name + ".krak")) error("could not compile")
var results_file_name = test_name + ".results"
var expected_results_file_name = test_name + ".expected_results"
if (system(string("./") + test_name + " > " + results_file_name)) error("could not run")
if (system(kraken_path + " " + test_name + ".krak > " + results_file_name)) error("could not compile")
if (system(string("./") + test_name + " >> " + results_file_name)) error("could not run")
if (file_exists(results_file_name) && file_exists(expected_results_file_name) && read_file(results_file_name) == read_file(expected_results_file_name)) {
println(test_name + "\tPASSED!")
all_results += pad_with_spaces(test_name) + "\tPASSED!\n"