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:
@@ -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)|
|
||||
|[ -!]|(\\\"))*\"" ;
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user