[Compiler] Support array fields in static objects (#284)

* first part of static inline array fields

* level h
This commit is contained in:
water111 2021-02-25 22:49:46 -05:00 committed by GitHub
parent 791c4abfc0
commit cadd014add
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 408 additions and 73 deletions

View file

@ -207,8 +207,6 @@
) )
(define-extern *level* level-group) (define-extern *level* level-group)
;; OpenGOAL doesn not yet support setting fields to arrays in statics.
#|
(if (zero? *level*) (if (zero? *level*)
(set! *level* (set! *level*
(new 'static 'level-group (new 'static 'level-group
@ -225,28 +223,28 @@
:name #f :name #f
:status 'inactive :status 'inactive
:foreground-sink-group :foreground-sink-group
(new 'static 'inline-array 'dma-foreground-sink-group 3 (new 'static 'inline-array dma-foreground-sink-group 3
(new 'static 'dma-foreground-sink-group (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array 'dma-foreground-sink 3 :sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink :bucket 10) (new 'static 'dma-foreground-sink :bucket 10)
(new 'static 'generic-dma-foreground-sink (new 'static 'generic-dma-foreground-sink
:bucket 11 :foreground-output-bucket 1 :bucket 11 :foreground-output-bucket 1
) )
0) )
) )
(new 'static 'dma-foreground-sink-group (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array 'dma-foreground-sink 3 :sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink (new 'static 'dma-foreground-sink
:bucket 49 :bucket 49
:foreground-texture-page 1 :foreground-texture-page 1
) )
(new 'static 'generic-dma-foreground-sink : (new 'static 'generic-dma-foreground-sink
bucket 50 :foreground-texture-page 1 :bucket 50 :foreground-texture-page 1
:foreground-output-bucket 1) :foreground-output-bucket 1)
0) )
) )
(new 'static 'dma-foreground-sink-group (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array 'dma-foreground-sink 3 :sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink (new 'static 'dma-foreground-sink
:bucket 58 :bucket 58
:foreground-texture-page 2 :foreground-texture-page 2
@ -256,7 +254,7 @@
:foreground-texture-page 2 :foreground-texture-page 2
:foreground-output-bucket 1 :foreground-output-bucket 1
) )
0) )
) )
) )
:inside-sphere? #f :inside-sphere? #f
@ -269,9 +267,9 @@
:index 1 :index 1
:status 'inactive :status 'inactive
:foreground-sink-group :foreground-sink-group
(new 'static 'inline-array 'dma-foreground-sink-group 3 (new 'static 'inline-array dma-foreground-sink-group 3
(new 'static 'dma-foreground-sink-group (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array 'dma-foreground-sink 3 :sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink (new 'static 'dma-foreground-sink
:bucket 17 :bucket 17
:foreground-texture-level 1 :foreground-texture-level 1
@ -281,10 +279,10 @@
:foreground-texture-level 1 :foreground-texture-level 1
:foreground-output-bucket 1 :foreground-output-bucket 1
) )
0) )
) )
(new 'static 'dma-foreground-sink-group (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array 'dma-foreground-sink 3 :sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink (new 'static 'dma-foreground-sink
:bucket 52 :bucket 52
:foreground-texture-page 1 :foreground-texture-page 1
@ -296,11 +294,11 @@
:foreground-texture-level 1 :foreground-texture-level 1
:foreground-output-bucket 1 :foreground-output-bucket 1
) )
0
) )
) )
(new 'static 'dma-foreground-sink-group (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array 'dma-foreground-sink 3 :sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink (new 'static 'dma-foreground-sink
:bucket 61 :bucket 61
:foreground-texture-page 2 :foreground-texture-page 2
@ -312,7 +310,7 @@
:foreground-texture-level 1 :foreground-texture-level 1
:foreground-output-bucket 1 :foreground-output-bucket 1
) )
0) )
) )
) )
:inside-sphere? #f :inside-sphere? #f
@ -325,9 +323,9 @@
:index 2 :index 2
:status 'reserved :status 'reserved
:foreground-sink-group :foreground-sink-group
(new 'static 'inline-array 'dma-foreground-sink-group 3 (new 'static 'inline-array dma-foreground-sink-group 3
(new 'static 'dma-foreground-sink-group (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array 'dma-foreground-sink 3 :sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink (new 'static 'dma-foreground-sink
:bucket 45 :bucket 45
:foreground-texture-level 2 :foreground-texture-level 2
@ -337,10 +335,10 @@
:foreground-texture-level 2 :foreground-texture-level 2
:foreground-output-bucket 1 :foreground-output-bucket 1
) )
0)
) )
(new 'static 'dma-foreground-sink-group : )
sink (new 'static 'array 'dma-foreground-sink 3 (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink (new 'static 'dma-foreground-sink
:bucket 55 :bucket 55
:foreground-texture-page 1 :foreground-texture-page 1
@ -352,10 +350,10 @@
:foreground-texture-level 2 :foreground-texture-level 2
:foreground-output-bucket 1 :foreground-output-bucket 1
) )
0) )
) )
(new 'static 'dma-foreground-sink-group (new 'static 'dma-foreground-sink-group
:sink (new 'static 'array 'dma-foreground-sink 3 :sink (new 'static 'array dma-foreground-sink 3
(new 'static 'dma-foreground-sink (new 'static 'dma-foreground-sink
:bucket 58 :bucket 58
:foreground-texture-page 2 :foreground-texture-page 2
@ -367,7 +365,7 @@
:foreground-texture-level 2 :foreground-texture-level 2
:foreground-output-bucket 1 :foreground-output-bucket 1
) )
0
) )
) )
) )
@ -378,5 +376,4 @@
) )
) )
) )
|#

View file

@ -165,6 +165,23 @@ class Compiler {
bool boxed, bool boxed,
Env* env); Env* env);
StaticResult fill_static_inline_array(const goos::Object& form,
const goos::Object& rest,
Env* env);
void fill_static_inline_array_inline(const goos::Object& form,
const TypeSpec& content_type,
const std::vector<goos::Object>& args,
StaticStructure* structure,
int offset,
Env* env);
void fill_static_array_inline(const goos::Object& form,
const TypeSpec& content_type,
const std::vector<goos::Object>& args,
StaticStructure* structure,
int offset,
Env* env);
TypeSystem m_ts; TypeSystem m_ts;
std::unique_ptr<GlobalEnv> m_global_env = nullptr; std::unique_ptr<GlobalEnv> m_global_env = nullptr;
std::unique_ptr<None> m_none = nullptr; std::unique_ptr<None> m_none = nullptr;

View file

@ -90,7 +90,7 @@ StaticObject::LoadInfo StaticStructure::get_load_info() const {
} }
int StaticStructure::get_addr_offset() const { int StaticStructure::get_addr_offset() const {
return 0; return m_offset;
} }
void StaticStructure::generate_structure(emitter::ObjectGenerator* gen) { void StaticStructure::generate_structure(emitter::ObjectGenerator* gen) {

View file

@ -48,6 +48,7 @@ class StaticStructure : public StaticObject {
void generate_structure(emitter::ObjectGenerator* gen); void generate_structure(emitter::ObjectGenerator* gen);
void generate(emitter::ObjectGenerator* gen) override; void generate(emitter::ObjectGenerator* gen) override;
int get_addr_offset() const override; int get_addr_offset() const override;
void set_offset(int offset) { m_offset = offset; }
struct SymbolRecord { struct SymbolRecord {
int offset = -1; int offset = -1;
@ -67,6 +68,9 @@ class StaticStructure : public StaticObject {
void add_symbol_record(std::string name, int offset); void add_symbol_record(std::string name, int offset);
void add_pointer_record(int offset_in_this, StaticStructure* dest, int offset_in_dest); void add_pointer_record(int offset_in_this, StaticStructure* dest, int offset_in_dest);
void add_type_record(std::string name, int offset); void add_type_record(std::string name, int offset);
private:
int m_offset = 0;
}; };
class StaticBasic : public StaticStructure { class StaticBasic : public StaticStructure {

View file

@ -78,13 +78,82 @@ void Compiler::compile_static_structure_inline(const goos::Object& form,
field_name_def = field_name_def.substr(1); field_name_def = field_name_def.substr(1);
auto field_info = m_ts.lookup_field_info(type_info->get_name(), field_name_def); auto field_info = m_ts.lookup_field_info(type_info->get_name(), field_name_def);
if (field_info.field.is_dynamic() || field_info.field.is_array()) { if (field_info.field.is_dynamic()) {
throw_compiler_error(form, "Static objects not yet implemented for dynamic/inline/array"); throw_compiler_error(form, "Dynamic fields are not supported for inline");
} }
auto field_offset = field_info.field.offset() + offset; auto field_offset = field_info.field.offset() + offset;
if (is_integer(field_info.type)) { if (field_info.field.is_array()) {
bool is_inline = field_info.field.is_inline();
// for an array field, we only accept (new 'static 'array <type> ...)
if (!field_value.is_list()) {
throw_compiler_error(field_value, "Array field was not properly specified");
}
goos::Object constructor_args;
auto new_form = get_list_as_vector(field_value, &constructor_args, 5);
if (new_form.size() != 5) {
throw_compiler_error(
field_value,
"Array field must be defined with (new 'static ['array, 'inline-array] type-name ...)");
}
if (!new_form.at(0).is_symbol() || new_form.at(0).as_symbol()->name != "new") {
throw_compiler_error(
field_value,
"Array field must be defined with (new 'static ['array, 'inline-array] type-name ...)");
}
if (!is_quoted_sym(new_form.at(1)) || unquote(new_form.at(1)).as_symbol()->name != "static") {
throw_compiler_error(
field_value,
"Array field must be defined with (new 'static ['array, 'inline-array] type-name ...)");
}
if (unquote(new_form.at(2)).print() != (is_inline ? "inline-array" : "array")) {
throw_compiler_error(
field_value,
"Array field must be defined with (new 'static ['array, 'inline-array] type-name ...)");
}
auto array_content_type = parse_typespec(new_form.at(3));
if (is_inline) {
if (field_info.field.type() != array_content_type) {
throw_compiler_error(field_value, "Inline array field must have the correct type");
}
} else {
// allow more specific types.
m_ts.typecheck(field_info.field.type(), array_content_type, "Array content type");
}
s64 elt_array_len;
if (!try_getting_constant_integer(new_form.at(4), &elt_array_len, env)) {
throw_compiler_error(field_value, "Array field size is invalid, got {}",
new_form.at(4).print());
}
if (elt_array_len != field_info.field.array_size()) {
throw_compiler_error(field_value, "Array field had an expected size of {} but got {}",
field_info.field.array_size(), elt_array_len);
}
auto arg_list = get_list_as_vector(field_value.as_pair()->cdr);
if (((int)arg_list.size() - 5) > elt_array_len) {
throw_compiler_error(field_value, "Array field definition has too many values in it.");
}
if (is_inline) {
fill_static_inline_array_inline(field_value, field_info.field.type(), arg_list, structure,
field_offset, env);
} else {
fill_static_array_inline(field_value, field_info.field.type(), arg_list, structure,
field_offset, env);
}
} else if (is_integer(field_info.type)) {
assert(field_info.needs_deref); // for now... assert(field_info.needs_deref); // for now...
auto deref_info = m_ts.get_deref_info(m_ts.make_pointer_typespec(field_info.type)); auto deref_info = m_ts.get_deref_info(m_ts.make_pointer_typespec(field_info.type));
auto field_size = deref_info.load_size; auto field_size = deref_info.load_size;
@ -162,7 +231,7 @@ void Compiler::compile_static_structure_inline(const goos::Object& form,
assert(field_offset + field_size <= int(structure->data.size())); assert(field_offset + field_size <= int(structure->data.size()));
auto sr = compile_static(field_value, env); auto sr = compile_static(field_value, env);
if (sr.is_symbol()) { if (sr.is_symbol()) {
if (sr.symbol_name() != "#f") { if (sr.symbol_name() != "#f" && sr.symbol_name() != "_empty_") {
typecheck(form, field_info.type, sr.typespec()); typecheck(form, field_info.type, sr.typespec());
} }
structure->add_symbol_record(sr.symbol_name(), field_offset); structure->add_symbol_record(sr.symbol_name(), field_offset);
@ -437,6 +506,8 @@ StaticResult Compiler::compile_static(const goos::Object& form, Env* env) {
return fill_static_array(form, rest, true, env); return fill_static_array(form, rest, true, env);
} else if (unquote(args.at(1)).as_symbol()->name == "array") { } else if (unquote(args.at(1)).as_symbol()->name == "array") {
return fill_static_array(form, rest, false, env); return fill_static_array(form, rest, false, env);
} else if (unquote(args.at(1)).as_symbol()->name == "inline-array") {
return fill_static_inline_array(form, rest, env);
} else { } else {
auto ts = parse_typespec(unquote(args.at(1))); auto ts = parse_typespec(unquote(args.at(1)));
if (ts == TypeSpec("string")) { if (ts == TypeSpec("string")) {
@ -485,6 +556,46 @@ StaticResult Compiler::compile_static(const goos::Object& form, Env* env) {
return {}; return {};
} }
void Compiler::fill_static_array_inline(const goos::Object& form,
const TypeSpec& content_type,
const std::vector<goos::Object>& args,
StaticStructure* structure,
int offset,
Env* env) {
auto pointer_type = m_ts.make_pointer_typespec(content_type);
auto deref_info = m_ts.get_deref_info(pointer_type);
assert(deref_info.can_deref);
assert(deref_info.mem_deref);
for (size_t i = 4; i < args.size(); i++) {
int arg_idx = i - 4;
int elt_offset = offset + arg_idx * deref_info.stride;
auto sr = compile_static(args.at(i), env);
if (is_integer(content_type)) {
typecheck(form, TypeSpec("integer"), sr.typespec());
} else {
typecheck(form, content_type, sr.typespec());
}
if (sr.is_symbol()) {
assert(deref_info.stride == 4);
structure->add_symbol_record(sr.symbol_name(), elt_offset);
u32 symbol_placeholder = 0xffffffff;
memcpy(structure->data.data() + elt_offset, &symbol_placeholder, 4);
} else if (sr.is_reference()) {
assert(deref_info.stride == 4);
structure->add_pointer_record(elt_offset, sr.reference(), sr.reference()->get_addr_offset());
} else if (sr.is_constant_data()) {
if (!integer_fits(sr.constant_data(), deref_info.load_size, deref_info.sign_extend)) {
throw_compiler_error(form, "The integer {} doesn't fit in element {} of array of {}",
sr.constant_data(), arg_idx, content_type.print());
}
u64 data = sr.constant_data();
memcpy(structure->data.data() + elt_offset, &data, deref_info.load_size);
} else {
assert(false);
}
}
}
StaticResult Compiler::fill_static_array(const goos::Object& form, StaticResult Compiler::fill_static_array(const goos::Object& form,
const goos::Object& rest, const goos::Object& rest,
bool boxed, bool boxed,
@ -530,34 +641,8 @@ StaticResult Compiler::fill_static_array(const goos::Object& form,
} }
// now add arguments: // now add arguments:
for (size_t i = 4; i < args.size(); i++) { fill_static_array_inline(form, content_type, args, obj.get(), array_header_size, env);
int arg_idx = i - 4;
int elt_offset = array_header_size + arg_idx * deref_info.stride;
auto sr = compile_static(args.at(i), env);
if (is_integer(content_type)) {
typecheck(form, TypeSpec("integer"), sr.typespec());
} else {
typecheck(form, content_type, sr.typespec());
}
if (sr.is_symbol()) {
assert(deref_info.stride == 4);
obj->add_symbol_record(sr.symbol_name(), elt_offset);
u32 symbol_placeholder = 0xffffffff;
memcpy(obj->data.data() + elt_offset, &symbol_placeholder, 4);
} else if (sr.is_reference()) {
assert(deref_info.stride == 4);
obj->add_pointer_record(elt_offset, sr.reference(), sr.reference()->get_addr_offset());
} else if (sr.is_constant_data()) {
if (!integer_fits(sr.constant_data(), deref_info.load_size, deref_info.sign_extend)) {
throw_compiler_error(form, "The integer {} doesn't fit in element {} of array of {}",
sr.constant_data(), arg_idx, content_type.print());
}
u64 data = sr.constant_data();
memcpy(obj->data.data() + elt_offset, &data, deref_info.load_size);
} else {
assert(false);
}
}
TypeSpec result_type; TypeSpec result_type;
if (boxed) { if (boxed) {
result_type = m_ts.make_array_typespec(content_type); result_type = m_ts.make_array_typespec(content_type);
@ -569,6 +654,91 @@ StaticResult Compiler::fill_static_array(const goos::Object& form,
return result; return result;
} }
void Compiler::fill_static_inline_array_inline(const goos::Object& form,
const TypeSpec& content_type,
const std::vector<goos::Object>& args,
StaticStructure* structure,
int offset,
Env* env) {
auto inline_array_type = m_ts.make_inline_array_typespec(content_type);
auto deref_info = m_ts.get_deref_info(inline_array_type);
assert(deref_info.can_deref);
assert(!deref_info.mem_deref);
for (size_t i = 4; i < args.size(); i++) {
auto arg_idx = i - 4;
int elt_offset = arg_idx * deref_info.stride;
auto& elt_def = args.at(i);
if (!elt_def.is_list()) {
throw_compiler_error(form, "Element in static inline-array must be a {}. Got {}",
content_type.print(), elt_def.print());
}
goos::Object ctor_args;
auto new_form = get_list_as_vector(elt_def, &ctor_args, 3);
if (new_form.size() != 3) {
throw_compiler_error(
elt_def, "Inline array element must be defined with (new 'static 'type-name ...)");
}
if (!new_form.at(0).is_symbol() || new_form.at(0).as_symbol()->name != "new") {
throw_compiler_error(
elt_def, "Inline array element must be defined with (new 'static 'type-name ...)");
}
if (!is_quoted_sym(new_form.at(1)) || unquote(new_form.at(1)).as_symbol()->name != "static") {
throw_compiler_error(
elt_def, "Inline array element must be defined with (new 'static 'type-name ...)");
}
auto inlined_type = parse_typespec(unquote(new_form.at(2)));
if (inlined_type != content_type) {
throw_compiler_error(elt_def, "Cannot store a {} in an inline array of {}",
inlined_type.print(), content_type.print());
}
compile_static_structure_inline(elt_def, content_type, ctor_args, structure,
elt_offset + offset, env);
if (is_basic(content_type)) {
structure->add_type_record(content_type.base_type(), elt_offset + offset);
}
}
}
StaticResult Compiler::fill_static_inline_array(const goos::Object& form,
const goos::Object& rest,
Env* env) {
auto fie = get_parent_env_of_type<FileEnv>(env);
// (new 'static 'inline-array ...)
// get all arguments now
auto args = get_list_as_vector(rest);
if (args.size() < 4) {
throw_compiler_error(form, "new static boxed array must have type and min-size arguments");
}
auto content_type = parse_typespec(args.at(2));
s64 min_size;
if (!try_getting_constant_integer(args.at(3), &min_size, env)) {
throw_compiler_error(form, "The length {} is not valid.", args.at(3).print());
}
s32 length = std::max(min_size, s64(args.size() - 4));
auto inline_array_type = m_ts.make_inline_array_typespec(content_type);
auto deref_info = m_ts.get_deref_info(inline_array_type);
assert(deref_info.can_deref);
assert(!deref_info.mem_deref);
// todo
auto obj = std::make_unique<StaticStructure>(MAIN_SEGMENT);
obj->set_offset(is_basic(content_type) ? 4 : 0);
obj->data.resize(length * deref_info.stride);
// now add elements:
fill_static_inline_array_inline(form, content_type, args, obj.get(), 0, env);
TypeSpec result_type = m_ts.make_inline_array_typespec(content_type);
auto result = StaticResult::make_structure_reference(obj.get(), result_type);
fie->add_static(std::move(obj));
return result;
}
Val* Compiler::compile_new_static_bitfield(const goos::Object& form, Val* Compiler::compile_new_static_bitfield(const goos::Object& form,
const TypeSpec& type, const TypeSpec& type,
const goos::Object& _field_defs, const goos::Object& _field_defs,

View file

@ -766,7 +766,8 @@ Val* Compiler::compile_static_new(const goos::Object& form,
Env* env) { Env* env) {
auto unquoted = unquote(type); auto unquoted = unquote(type);
if (unquoted.is_symbol() && if (unquoted.is_symbol() &&
(unquoted.as_symbol()->name == "boxed-array" || unquoted.as_symbol()->name == "array")) { (unquoted.as_symbol()->name == "boxed-array" || unquoted.as_symbol()->name == "array" ||
unquoted.as_symbol()->name == "inline-array")) {
auto fe = get_parent_env_of_type<FunctionEnv>(env); auto fe = get_parent_env_of_type<FunctionEnv>(env);
auto sr = compile_static(form, env); auto sr = compile_static(form, env);
auto result = fe->alloc_val<StaticVal>(sr.reference(), sr.typespec()); auto result = fe->alloc_val<StaticVal>(sr.reference(), sr.typespec());

View file

@ -0,0 +1,17 @@
(deftype test-basic-for-static-array-field (basic)
((value uint32)
(name string)
(arr basic 12)
(lst pair)
)
)
(let ((test (new 'static 'test-basic-for-static-array-field
:value 12
:arr (new 'static 'array basic 12
"asdf"
"ghjkl"
)
)))
(format #t "~A~%" (-> test arr 1))
)

View file

@ -0,0 +1,57 @@
(deftype basic-elt (basic)
((name string))
)
(deftype struct-elt (structure)
((thing symbol))
)
(deftype test-basic-for-static-inline-array-field (basic)
((value uint32)
(name string)
(arr basic-elt 12 :inline)
(arr2 struct-elt 3 :inline)
(lst pair)
)
)
(let ((test (new 'static 'test-basic-for-static-inline-array-field
:value 12
:arr (new 'static 'inline-array basic-elt 12
(new 'static 'basic-elt :name "first")
(new 'static 'basic-elt :name "second")
)
:arr2 (new 'static 'inline-array struct-elt 3
(new 'static 'struct-elt :thing 'asdf)
(new 'static 'struct-elt :thing 'two)
)
)))
(format #t "~A ~A~%" (-> test arr 1 name) (-> test arr 0 name))
(format #t "~A #x~X #x~X~%" (-> test arr 1 type) (logand 15 (the int (-> test arr))) (logand 15 (the int (-> test arr 1))))
(format #t "~A~%" (-> test arr2 1 thing))
)
(deftype test-struct-for-static-inline-array-field (structure)
((value uint32)
(name string)
(arr basic-elt 12 :inline)
(arr2 struct-elt 3 :inline)
(lst pair)
)
)
(let ((test (new 'static 'test-struct-for-static-inline-array-field
:value 12
:arr (new 'static 'inline-array basic-elt 12
(new 'static 'basic-elt :name "first")
(new 'static 'basic-elt :name "second")
)
:arr2 (new 'static 'inline-array struct-elt 3
(new 'static 'struct-elt :thing 'asdf)
(new 'static 'struct-elt :thing 'two)
)
)))
(format #t "~A ~A~%" (-> test arr 1 name) (-> test arr 0 name))
(format #t "~A #x~X #x~X~%" (-> test arr 1 type) (logand 15 (the int (-> test arr))) (logand 15 (the int (-> test arr 1))))
(format #t "~A~%" (-> test arr2 1 thing))
)

View file

@ -0,0 +1,47 @@
(deftype test-basic-for-static-inline (basic)
((value uint32)
(name string)
(thing symbol)
(lst pair)
)
)
(let ((test-arr (new 'static 'inline-array test-basic-for-static-inline 3
(new 'static 'test-basic-for-static-inline :value 12 :name "test-name" :thing 'beans :lst '("asdf" b ( c . d)))
(new 'static 'test-basic-for-static-inline :value 1235 :name "hello")
)
)
)
(format #t "~A ~A #x~X #x~X ~A~%"
(-> test-arr 0 type)
(-> test-arr 1 type)
(logand 15 (the int (-> test-arr 1)))
(logand 15 (the int test-arr))
(-> test-arr 1 name)
)
)
(deftype test-struct-for-static-inline (structure)
((value uint32)
(name string)
(thing symbol)
(lst pair)
)
)
(let ((test-arr (new 'static 'inline-array test-struct-for-static-inline 3
(new 'static 'test-struct-for-static-inline :value 12 :name "test-name" :thing 'beans :lst '("asdf" b ( c . d)))
(new 'static 'test-struct-for-static-inline :value 1235 :name "hello")
)
)
)
(format #t "#x~X #x~X ~A~%"
;;(-> test-arr 0 type)
;;(-> test-arr 1 type)
(logand 15 (the int (-> test-arr 1)))
(logand 15 (the int test-arr))
(-> test-arr 1 name)
)
)

View file

@ -493,6 +493,31 @@ TEST_F(WithGameTests, StaticArray) {
"0\n"}); "0\n"});
} }
TEST_F(WithGameTests, StaticInlineArray) {
runner.run_static_test(
env, testCategory, "test-static-inline-array.gc",
{"test-basic-for-static-inline test-basic-for-static-inline #x4 #x4 \"hello\"\n"
"#x0 #x0 \"hello\"\n"
"0\n"});
}
TEST_F(WithGameTests, StaticArrayField) {
runner.run_static_test(env, testCategory, "test-static-array-field.gc",
{"\"ghjkl\"\n"
"0\n"});
}
TEST_F(WithGameTests, StaticFieldInlineArray) {
runner.run_static_test(env, testCategory, "test-static-field-inline-arrays.gc",
{"\"second\" \"first\"\n"
"basic-elt #x4 #x4\n"
"two\n"
"\"second\" \"first\"\n"
"basic-elt #x4 #x4\n"
"two\n"
"0\n"});
}
TEST(TypeConsistency, TypeConsistency) { TEST(TypeConsistency, TypeConsistency) {
Compiler compiler; Compiler compiler;
compiler.enable_throw_on_redefines(); compiler.enable_throw_on_redefines();