mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
Merge pull request #97 from water111/w/add-types-to-all-types
Add some types
This commit is contained in:
commit
fd8a0a5cf1
|
@ -300,6 +300,14 @@ class Object {
|
|||
return float_obj.value;
|
||||
}
|
||||
|
||||
const FloatType& as_float() const {
|
||||
if (type != ObjectType::FLOAT) {
|
||||
throw std::runtime_error("as_float called on a " + object_type_to_string(type) + " " +
|
||||
print());
|
||||
}
|
||||
return float_obj.value;
|
||||
}
|
||||
|
||||
char& as_char() {
|
||||
if (type != ObjectType::CHAR) {
|
||||
throw std::runtime_error("as_char called on a " + object_type_to_string(type) + " " +
|
||||
|
|
|
@ -239,7 +239,13 @@ StructureDefResult parse_structure_def(StructureType* type,
|
|||
result.generate_runtime_type = false;
|
||||
} else if (opt_name == ":pack-me") {
|
||||
result.pack_me = true;
|
||||
} else {
|
||||
} else if (opt_name == ":heap-base") {
|
||||
u16 hb = get_int(car(rest));
|
||||
rest = cdr(rest);
|
||||
flags.heap_base = hb;
|
||||
}
|
||||
|
||||
else {
|
||||
throw std::runtime_error("Invalid option in field specification: " + opt_name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -312,10 +312,13 @@ bool get_ptr_offset(IR* ir, Register dst, Register base, int* result) {
|
|||
get_ptr_offset_zero(as_math, base, result);
|
||||
}
|
||||
|
||||
bool is_weird(Function& function, LinkedObjectFile& file, TypeInspectorResult* result) {
|
||||
int get_start_idx(Function& function,
|
||||
LinkedObjectFile& file,
|
||||
TypeInspectorResult* result,
|
||||
const std::string& parent_type) {
|
||||
if (function.basic_blocks.size() > 1) {
|
||||
result->warnings += " too many basic blocks";
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -341,64 +344,94 @@ bool is_weird(Function& function, LinkedObjectFile& file, TypeInspectorResult* r
|
|||
// check size
|
||||
if (function.basic_ops.size() < 7) {
|
||||
result->warnings += " not enough basic ops";
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& move_op = function.basic_ops.at(0);
|
||||
if (!is_reg_reg_move(move_op.get(), make_gpr(Reg::GP), make_gpr(Reg::A0))) {
|
||||
result->warnings += "bad first move";
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& get_format_op = function.basic_ops.at(1);
|
||||
if (!is_get_sym_value(get_format_op.get(), make_gpr(Reg::T9), "format")) {
|
||||
result->warnings += "bad get format";
|
||||
return true;
|
||||
|
||||
if (is_get_sym_value(get_format_op.get(), make_gpr(Reg::T9), "format")) {
|
||||
auto& get_true = function.basic_ops.at(2);
|
||||
if (!is_get_sym(get_true.get(), make_gpr(Reg::A0), "#t")) {
|
||||
result->warnings += "bad get true";
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& get_str = function.basic_ops.at(3);
|
||||
if (!is_get_label(get_str.get(), make_gpr(Reg::A1))) {
|
||||
result->warnings += "bad get label";
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto str = file.get_goal_string_by_label(file.labels.at(get_label_id_of_set(get_str.get())));
|
||||
if (str != "[~8x] ~A~%") {
|
||||
result->warnings += "bad type dec string: " + str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& move2_op = function.basic_ops.at(4);
|
||||
if (!is_reg_reg_move(move2_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP))) {
|
||||
result->warnings += "bad second move";
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& load_op = function.basic_ops.at(5);
|
||||
bool is_basic_load = is_get_load_with_offset(load_op.get(), make_gpr(Reg::A3),
|
||||
IR_Load::UNSIGNED, 4, make_gpr(Reg::GP), -4);
|
||||
result->is_basic = is_basic_load;
|
||||
|
||||
bool is_struct_load = is_get_sym(load_op.get(), make_gpr(Reg::A3), function.method_of_type);
|
||||
|
||||
if (!is_basic_load && !is_struct_load) {
|
||||
result->warnings += "bad load";
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& call = function.basic_ops.at(6);
|
||||
if (!dynamic_cast<IR_Call*>(call.get())) {
|
||||
result->warnings += "bad call";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// okay!
|
||||
return 7;
|
||||
} else {
|
||||
if (is_get_sym_value(get_format_op.get(), make_gpr(Reg::V1), parent_type)) {
|
||||
// now get the inspect method.
|
||||
auto& get_method_op = function.basic_ops.at(2);
|
||||
if (!is_get_load_with_offset(get_method_op.get(), make_gpr(Reg::T9), IR_Load::UNSIGNED, 4,
|
||||
make_gpr(Reg::V1), 28)) {
|
||||
result->warnings += "bad get method op " + get_method_op->print(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& move2_op = function.basic_ops.at(3);
|
||||
if (!is_reg_reg_move(move2_op.get(), make_gpr(Reg::A0), make_gpr(Reg::GP))) {
|
||||
result->warnings += "bad move2 op " + move2_op->print(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& call_op = function.basic_ops.at(4);
|
||||
if (!dynamic_cast<IR_Call*>(call_op.get())) {
|
||||
result->warnings += "bad call op " + call_op->print(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
result->warnings += "inherited inpspect of " + parent_type;
|
||||
result->is_basic = true;
|
||||
return 5;
|
||||
|
||||
} else {
|
||||
result->warnings +=
|
||||
"unrecognized get op: " + get_format_op->print(file) + " parent was " + parent_type;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto& get_true = function.basic_ops.at(2);
|
||||
if (!is_get_sym(get_true.get(), make_gpr(Reg::A0), "#t")) {
|
||||
result->warnings += "bad get true";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& get_str = function.basic_ops.at(3);
|
||||
if (!is_get_label(get_str.get(), make_gpr(Reg::A1))) {
|
||||
result->warnings += "bad get label";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto str = file.get_goal_string_by_label(file.labels.at(get_label_id_of_set(get_str.get())));
|
||||
if (str != "[~8x] ~A~%") {
|
||||
result->warnings += "bad type dec string: " + str;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& move2_op = function.basic_ops.at(4);
|
||||
if (!is_reg_reg_move(move2_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP))) {
|
||||
result->warnings += "bad second move";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& load_op = function.basic_ops.at(5);
|
||||
bool is_basic_load = is_get_load_with_offset(load_op.get(), make_gpr(Reg::A3), IR_Load::UNSIGNED,
|
||||
4, make_gpr(Reg::GP), -4);
|
||||
result->is_basic = is_basic_load;
|
||||
|
||||
bool is_struct_load = is_get_sym(load_op.get(), make_gpr(Reg::A3), function.method_of_type);
|
||||
|
||||
if (!is_basic_load && !is_struct_load) {
|
||||
result->warnings += "bad load";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& call = function.basic_ops.at(6);
|
||||
if (!dynamic_cast<IR_Call*>(call.get())) {
|
||||
result->warnings += "bad call";
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int identify_basic_field(int idx,
|
||||
|
@ -706,11 +739,11 @@ TypeInspectorResult inspect_inspect_method(Function& inspect,
|
|||
assert(flags.pad == 0);
|
||||
|
||||
auto& bad_set = get_config().bad_inspect_types;
|
||||
if (is_weird(inspect, file, &result) || bad_set.find(type_name) != bad_set.end()) {
|
||||
int idx = get_start_idx(inspect, file, &result, result.parent_type_name);
|
||||
if (idx == 0 || bad_set.find(type_name) != bad_set.end()) {
|
||||
// printf("was weird: %s\n", result.warnings.c_str());
|
||||
return result;
|
||||
}
|
||||
int idx = 7;
|
||||
while (idx < int(inspect.basic_ops.size()) - 1 && idx != -1) {
|
||||
idx = detect(idx, inspect, file, &result);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,14 +3,14 @@
|
|||
{
|
||||
"game_version":1,
|
||||
// the order here matters. KERNEL and GAME should go first
|
||||
"dgo_names":["CGO/KERNEL.CGO","CGO/GAME.CGO"], /*
|
||||
, "CGO/ENGINE.CGO"
|
||||
"dgo_names":["CGO/KERNEL.CGO","CGO/GAME.CGO",
|
||||
"CGO/ENGINE.CGO"
|
||||
, "CGO/ART.CGO", "DGO/BEA.DGO", "DGO/CIT.DGO", "CGO/COMMON.CGO", "DGO/DAR.DGO", "DGO/DEM.DGO",
|
||||
"DGO/FIN.DGO", "DGO/INT.DGO", "DGO/JUB.DGO", "DGO/JUN.DGO", "CGO/JUNGLE.CGO", "CGO/L1.CGO", "DGO/FIC.DGO",
|
||||
"DGO/LAV.DGO", "DGO/MAI.DGO", "CGO/MAINCAVE.CGO", "DGO/MIS.DGO", "DGO/OGR.DGO", "CGO/RACERP.CGO", "DGO/ROB.DGO", "DGO/ROL.DGO",
|
||||
"DGO/SNO.DGO", "DGO/SUB.DGO", "DGO/SUN.DGO", "CGO/SUNKEN.CGO", "DGO/SWA.DGO", "DGO/TIT.DGO", "DGO/TRA.DGO", "DGO/VI1.DGO",
|
||||
"DGO/VI2.DGO", "DGO/VI3.DGO", "CGO/VILLAGEP.CGO", "CGO/WATER-AN.CGO"
|
||||
],*/
|
||||
],
|
||||
|
||||
"write_disassembly":true,
|
||||
"write_hex_near_instructions":false,
|
||||
|
@ -34,7 +34,8 @@
|
|||
"types_with_bad_inspect_methods":[
|
||||
"engine",
|
||||
"bsp-header",
|
||||
"joint-anim-matrix"
|
||||
"joint-anim-matrix",
|
||||
"part-tracker"
|
||||
],
|
||||
|
||||
"asm_functions_by_name":[
|
||||
|
|
|
@ -58,6 +58,19 @@ void DecompilerTypeSystem::parse_type_defs(const std::vector<std::string>& file_
|
|||
|
||||
} else if (car(o).as_symbol()->name == "deftype") {
|
||||
parse_deftype(cdr(o), &ts);
|
||||
} else if (car(o).as_symbol()->name == "declare-type") {
|
||||
auto* rest = &cdr(o);
|
||||
auto type_name = car(*rest);
|
||||
rest = &cdr(*rest);
|
||||
auto type_kind = car(*rest);
|
||||
if (!cdr(*rest).is_empty_list()) {
|
||||
throw std::runtime_error("malformed declare-type");
|
||||
}
|
||||
if (type_kind.as_symbol()->name == "basic") {
|
||||
ts.forward_declare_type_as_basic(type_name.as_symbol()->name);
|
||||
} else {
|
||||
throw std::runtime_error("bad declare-type");
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("Decompiler cannot parse " + car(o).print());
|
||||
}
|
||||
|
|
|
@ -39,4 +39,8 @@
|
|||
- The `&+` form now accepts more than two arguments.
|
||||
- The `&+` form now works on `inline-array` and `structure`.
|
||||
- In the case where the type system would use a result type of `lca(none, x)`, the result type is now `none` instead of compiler abort.
|
||||
- The "none value" is now `(none)` instead of `none`
|
||||
- The "none value" is now `(none)` instead of `none`
|
||||
|
||||
- Creating a field of 128-bit value type no longer causes a compiler crash
|
||||
- 128-bit fields are inspected as `<cannot-print>`
|
||||
- Static fields can now contain floating point values
|
|
@ -5,3 +5,429 @@
|
|||
;; name in dgo: vector-h
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; bit array
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(deftype bit-array (basic)
|
||||
((length int32 :offset-assert 4)
|
||||
(allocated-length int32 :offset-assert 8)
|
||||
(_pad uint8)
|
||||
)
|
||||
:method-count-assert 13
|
||||
:size-assert #xd
|
||||
:flag-assert #xd0000000d
|
||||
(:methods
|
||||
(dummy-9 () none 9)
|
||||
(dummy-10 () none 10)
|
||||
(dummy-11 () none 11)
|
||||
(dummy-12 () none 12)
|
||||
)
|
||||
)
|
||||
|
||||
;; todo new
|
||||
;; todo 4
|
||||
;; todo 5
|
||||
;; todo 9
|
||||
;; todo 10
|
||||
;; todo 11
|
||||
;; todo 12
|
||||
;;
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; vector types (integer)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Vector of 4 unsigned bytes.
|
||||
(deftype vector4ub (structure)
|
||||
((data uint8 4 :offset-assert 0)
|
||||
(x uint8 :offset 0)
|
||||
(y uint8 :offset 1)
|
||||
(z uint8 :offset 2)
|
||||
(w uint8 :offset 3)
|
||||
(clr uint32 :offset 0)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; Vector of 4 signed bytes
|
||||
(deftype vector4b (structure)
|
||||
((data int8 4 :offset-assert 0)
|
||||
(x int8 :offset 0)
|
||||
(y int8 :offset 1)
|
||||
(z int8 :offset 2)
|
||||
(w int8 :offset 3)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; Vector of 2 signed halfwords
|
||||
(deftype vector2h (structure)
|
||||
((data int16 2 :offset-assert 0)
|
||||
(x int16 :offset 0)
|
||||
(y int16 :offset 2)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; Vector of 2 unsigned halfwords
|
||||
(deftype vector2uh (structure)
|
||||
((data uint16 2 :offset-assert 0)
|
||||
(x uint16 :offset 0)
|
||||
(y uint16 :offset 2)
|
||||
(val uint32 :offset 0)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; Vector of 3 halfwords
|
||||
(deftype vector3h (structure)
|
||||
((data int16 2 :offset-assert 0) ;; probably a bug, should be 3.
|
||||
(x int16 :offset 0)
|
||||
(y int16 :offset 2)
|
||||
(z int16 :offset-assert 4)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x6
|
||||
:flag-assert #x900000006
|
||||
)
|
||||
|
||||
;; Vector of 2 signed words
|
||||
(deftype vector2w (structure)
|
||||
((data int32 2 :offset-assert 0)
|
||||
(x int32 :offset 0)
|
||||
(y int32 :offset 4)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; Vector of 3 signed words
|
||||
(deftype vector3w (structure)
|
||||
((data int32 3 :offset-assert 0)
|
||||
(x int32 :offset 0)
|
||||
(y int32 :offset 4)
|
||||
(z int32 :offset 8)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #xc
|
||||
:flag-assert #x90000000c
|
||||
)
|
||||
|
||||
;; Vector of 4 signed words
|
||||
(deftype vector4w (structure)
|
||||
((data int32 4 :offset-assert 0)
|
||||
(x int32 :offset 0)
|
||||
(y int32 :offset 4)
|
||||
(z int32 :offset 8)
|
||||
(w int32 :offset 12)
|
||||
(dword uint64 2 :offset 0)
|
||||
(quad uint128 :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(defmethod print vector4w ((this vector4w))
|
||||
(format #t "#<vector4w ~D ~D ~D ~D @ #x~X>"
|
||||
(-> this data 0)
|
||||
(-> this data 1)
|
||||
(-> this data 2)
|
||||
(-> this data 3)
|
||||
this)
|
||||
this
|
||||
)
|
||||
|
||||
;; Two vector4w's
|
||||
(deftype vector4w-2 (structure)
|
||||
((data int32 8 :offset-assert 0)
|
||||
(quad uint128 2 :offset 0)
|
||||
(vector vector4w 2 :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
)
|
||||
|
||||
;; Three vector4w's
|
||||
(deftype vector4w-3 (structure)
|
||||
((data int32 12 :offset-assert 0)
|
||||
(quad uint128 3 :offset 0)
|
||||
(vector vector4w 3 :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x30
|
||||
:flag-assert #x900000030
|
||||
)
|
||||
|
||||
;; Four vector4w's
|
||||
(deftype vector4w-4 (structure)
|
||||
((data int32 16 :offset-assert 0)
|
||||
(quad uint128 4 :offset 0)
|
||||
(vector vector4w 4 :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x40
|
||||
:flag-assert #x900000040
|
||||
)
|
||||
|
||||
;; Vector of 4 halfwords
|
||||
(deftype vector4h (structure)
|
||||
((data int16 4 :offset-assert 0)
|
||||
(x int16 :offset 0)
|
||||
(y int16 :offset 2)
|
||||
(z int16 :offset 4)
|
||||
(w int16 :offset 6)
|
||||
(long uint64 :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; Vector of 8 halfwords
|
||||
(deftype vector8h (structure)
|
||||
((data int16 8 :offset-assert 0)
|
||||
(quad uint128 :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;; Vector of 16 signed bytes
|
||||
(deftype vector16b (structure)
|
||||
((data int8 8 :offset-assert 0)
|
||||
(quad uint128 :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; vector types (floating point)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Vector of 4 floats. Shortened to "vector" because it is commonly used.
|
||||
(deftype vector (structure)
|
||||
((data float 4 :offset-assert 0)
|
||||
(x float :offset 0)
|
||||
(y float :offset 4)
|
||||
(z float :offset 8)
|
||||
(w float :offset 12)
|
||||
(quad uint128 :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(defmethod inspect vector ((this vector))
|
||||
(format #t "[~8x] vector~%" this)
|
||||
(format #t "~T[~F] [~F] [~F] [~F]~%"
|
||||
(-> this data 0)
|
||||
(-> this data 1)
|
||||
(-> this data 2)
|
||||
(-> this data 3))
|
||||
this)
|
||||
|
||||
(defmethod print vector ((this vector))
|
||||
(format #t "#<vector ~F ~F ~F ~F @ #x~X>"
|
||||
(-> this data 0)
|
||||
(-> this data 1)
|
||||
(-> this data 2)
|
||||
(-> this data 3)
|
||||
this)
|
||||
this)
|
||||
|
||||
|
||||
(define *null-vector* (new 'static 'vector :x 0. :y 0. :z 0. :w 1.))
|
||||
(define *identity-vector* (new 'static 'vector :x 1. :y 1. :z 1. :w 1.))
|
||||
(define *x-vector* (new 'static 'vector :x 1. :y 0. :z 0. :w 1.))
|
||||
(define *y-vector* (new 'static 'vector :x 0. :y 1. :z 0. :w 1.))
|
||||
(define *z-vector* (new 'static 'vector :x 0. :y 0. :z 1. :w 1.))
|
||||
(define *up-vector* (new 'static 'vector :x 0. :y 1. :z 0. :w 1.))
|
||||
|
||||
|
||||
;; Three vector's
|
||||
(deftype vector4s-3 (structure)
|
||||
((data float 12 :offset-assert 0) ;; guess
|
||||
(quad uint128 3 :offset 0)
|
||||
(vector vector4w 3 :offset 0) ;; guess
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x30
|
||||
:flag-assert #x900000030
|
||||
)
|
||||
|
||||
(deftype vector-array (inline-array-class)
|
||||
(
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(set! (-> vector-array heap-base) 16)
|
||||
|
||||
(deftype rgbaf (vector)
|
||||
((r float :offset 0)
|
||||
(g float :offset 4)
|
||||
(b float :offset 8)
|
||||
(a float :offset 12)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(deftype plane (vector)
|
||||
((a float :offset 0)
|
||||
(b float :offset 4)
|
||||
(c float :offset 8)
|
||||
(d float :offset 12)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(deftype sphere (vector)
|
||||
((r float :offset 12)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
; (deftype isphere (vec4s)
|
||||
; ()
|
||||
; :method-count-assert 9
|
||||
; :size-assert #x10
|
||||
; :flag-assert #x900000010
|
||||
; )
|
||||
|
||||
(deftype box8s (structure)
|
||||
((data float 8 :offset-assert 0)
|
||||
(quad uint128 2 :offset 0)
|
||||
(vector vector 2 :offset 0)
|
||||
(min vector :inline :offset 0)
|
||||
(max vector :inline :offset 16)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
)
|
||||
|
||||
(deftype box8s-array (inline-array-class)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(set! (-> box8s-array heap-base) 32)
|
||||
|
||||
(deftype cylinder (structure)
|
||||
((origin vector :inline :offset-assert 0)
|
||||
(axis vector :inline :offset-assert 16)
|
||||
(radius float :offset-assert 32)
|
||||
(length float :offset-assert 36)
|
||||
)
|
||||
:method-count-assert 11
|
||||
:size-assert #x28
|
||||
:flag-assert #xb00000028
|
||||
(:methods
|
||||
(dummy-9 () none 9)
|
||||
(dummy-10 () none 10)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype cylinder-flat (structure)
|
||||
((origin vector :inline :offset-assert 0)
|
||||
(axis vector :inline :offset-assert 16)
|
||||
(radius float :offset-assert 32)
|
||||
(length float :offset-assert 36)
|
||||
)
|
||||
:method-count-assert 11
|
||||
:size-assert #x28
|
||||
:flag-assert #xb00000028
|
||||
(:methods
|
||||
(dummy-9 () none 9)
|
||||
(dummy-10 () none 10)
|
||||
)
|
||||
)
|
||||
|
||||
;; vector-h
|
||||
(deftype vertical-planes (structure)
|
||||
((data uint128 4 :offset-assert 0) ;; probably wrong
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x40
|
||||
:flag-assert #x900000040
|
||||
)
|
||||
|
||||
(deftype vertical-planes-array (basic)
|
||||
((length uint32 :offset-assert 4)
|
||||
(data vertical-planes :dynamic :offset 16) ;; todo, why is this here?
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(deftype qword (structure)
|
||||
((data uint32 4 :offset-assert 0)
|
||||
(byte uint8 16 :offset 0)
|
||||
(hword uint16 8 :offset 0)
|
||||
(word uint32 4 :offset 0)
|
||||
(dword uint64 2 :offset 0)
|
||||
(quad uint128 :offset 0)
|
||||
(vector vector :inline :offset 0)
|
||||
(vector4w vector4w :inline :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(deftype vector3s (structure)
|
||||
((data float 3 :offset-assert 0)
|
||||
(x float :offset 0)
|
||||
(y float :offset 4)
|
||||
(z float :offset 8)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #xc
|
||||
:flag-assert #x90000000c
|
||||
)
|
||||
|
||||
;; todo dot, dot-vu, 4-dot, 4-dot-vu, +!, -!, zero!, reset!, copy!
|
||||
|
||||
; (defun vector-dot ((a vector) (b vector))
|
||||
; "Take the dot product of two vectors.
|
||||
; Only does the x, y, z compoments"
|
||||
; (let ((result 0.))
|
||||
; (+! result (* (-> a x) (-> b x)))
|
||||
; (+! result (* (-> a y) (-> b y)))
|
||||
; (+! result (* (-> a z) (-> b z)))
|
||||
; )
|
||||
; result
|
||||
; )
|
||||
|
||||
(define *zero-vector* (new 'static 'vector :x 0. :y 0. :z 0. :w 0.))
|
|
@ -94,6 +94,7 @@ class Compiler {
|
|||
const std::string& method_type_name = "");
|
||||
|
||||
bool try_getting_constant_integer(const goos::Object& in, int64_t* out, Env* env);
|
||||
float try_getting_constant_float(const goos::Object& in, float* out, Env* env);
|
||||
|
||||
TypeSystem m_ts;
|
||||
std::unique_ptr<GlobalEnv> m_global_env = nullptr;
|
||||
|
@ -189,6 +190,7 @@ class Compiler {
|
|||
|
||||
// Math
|
||||
Val* compile_add(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
|
||||
Val* compile_sub(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
Val* compile_mul(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
Val* compile_div(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
|
|
|
@ -215,6 +215,17 @@ bool Compiler::try_getting_constant_integer(const goos::Object& in, int64_t* out
|
|||
return true;
|
||||
}
|
||||
|
||||
// todo, try more things like constants before giving up.
|
||||
return false;
|
||||
}
|
||||
|
||||
float Compiler::try_getting_constant_float(const goos::Object& in, float* out, Env* env) {
|
||||
(void)env;
|
||||
if (in.is_float()) {
|
||||
*out = in.as_float();
|
||||
return true;
|
||||
}
|
||||
|
||||
// todo, try more things like constants before giving up.
|
||||
return false;
|
||||
}
|
|
@ -119,6 +119,14 @@ Val* Compiler::compile_new_static_structure_or_basic(const goos::Object& form,
|
|||
throw_compile_error(
|
||||
form, "Setting a basic field to anything other than a symbol is currently unsupported");
|
||||
}
|
||||
} else if (is_float(field_info.type)) {
|
||||
float value = 0.f;
|
||||
if (!try_getting_constant_float(field_value, &value, env)) {
|
||||
throw_compile_error(form, fmt::format("Field {} is a float, but the value given couldn't "
|
||||
"be converted to a float at compile time.",
|
||||
field_name_def));
|
||||
}
|
||||
memcpy(obj->data.data() + field_offset, &value, sizeof(float));
|
||||
}
|
||||
|
||||
else {
|
||||
|
|
|
@ -111,24 +111,6 @@ void Compiler::generate_field_description(const goos::Object& form,
|
|||
if (m_ts.typecheck(m_ts.make_typespec("type"), f.type(), "", false, false)) {
|
||||
// type
|
||||
return;
|
||||
} else if (m_ts.typecheck(m_ts.make_typespec("basic"), f.type(), "", false, false) ||
|
||||
m_ts.typecheck(m_ts.make_typespec("binteger"), f.type(), "", false, false) ||
|
||||
m_ts.typecheck(m_ts.make_typespec("pair"), f.type(), "", false, false)) {
|
||||
// basic, binteger, pair
|
||||
str_template += fmt::format("~T{}: ~A~%", f.name());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
} else if (m_ts.typecheck(m_ts.make_typespec("integer"), f.type(), "", false, false)) {
|
||||
// Integer
|
||||
str_template += fmt::format("~T{}: ~D~%", f.name());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
} else if (m_ts.typecheck(m_ts.make_typespec("float"), f.type(), "", false, false)) {
|
||||
// Float
|
||||
str_template += fmt::format("~T{}: ~f~%", f.name());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
} else if (m_ts.typecheck(m_ts.make_typespec("pointer"), f.type(), "", false, false)) {
|
||||
// Pointers
|
||||
str_template += fmt::format("~T{}: #x~X~%", f.name());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
} else if (f.is_array() && !f.is_dynamic()) {
|
||||
// Arrays
|
||||
str_template += fmt::format("~T{}[{}] @ #x~X~%", f.name(), f.array_size());
|
||||
|
@ -141,6 +123,29 @@ void Compiler::generate_field_description(const goos::Object& form,
|
|||
// Structure
|
||||
str_template += fmt::format("~T{}: #<{} @ #x~X>~%", f.name(), f.type().print());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
} else if (m_ts.typecheck(m_ts.make_typespec("basic"), f.type(), "", false, false) ||
|
||||
m_ts.typecheck(m_ts.make_typespec("binteger"), f.type(), "", false, false) ||
|
||||
m_ts.typecheck(m_ts.make_typespec("pair"), f.type(), "", false, false)) {
|
||||
// basic, binteger, pair
|
||||
str_template += fmt::format("~T{}: ~A~%", f.name());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
} else if (m_ts.typecheck(m_ts.make_typespec("integer"), f.type(), "", false, false)) {
|
||||
// Integer
|
||||
if (f.type().print() == "uint128") {
|
||||
str_template += fmt::format("~T{}: <cannot-print>~%", f.name());
|
||||
} else {
|
||||
str_template += fmt::format("~T{}: ~D~%", f.name());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
}
|
||||
|
||||
} else if (m_ts.typecheck(m_ts.make_typespec("float"), f.type(), "", false, false)) {
|
||||
// Float
|
||||
str_template += fmt::format("~T{}: ~f~%", f.name());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
} else if (m_ts.typecheck(m_ts.make_typespec("pointer"), f.type(), "", false, false)) {
|
||||
// Pointers
|
||||
str_template += fmt::format("~T{}: #x~X~%", f.name());
|
||||
format_args.push_back(get_field_of_structure(type, reg, f.name(), env)->to_gpr(env));
|
||||
} else {
|
||||
// Otherwise, we havn't implemented it!
|
||||
str_template += fmt::format("~T{}: Undefined!~%", f.name());
|
||||
|
|
Loading…
Reference in a new issue