Add addition and subtraction for integers, build macros, dgo building, and build/load test (#35)

* see if math works on windows

* add dgo

* windows debug

* windows debug 2

* one more debug try

* add extra debug print and change logic for slashes

* update

* again

* try again

* remove build game

* remove build game

* add back build-game

* remove runtime from test

* test

* reduce number of files

* go to c++ 14

* big stacks

* increase stack size again

* clean up cmake files
This commit is contained in:
water111 2020-09-12 20:41:12 -04:00 committed by GitHub
parent d56540f8c0
commit 90a7e9b4b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 1133 additions and 27 deletions

View file

@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.16)
project(jak)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 14)
# Set default compile flags for GCC
# optimization level can be set here. Note that game/ overwrites this for building game C++ code.
@ -11,8 +11,8 @@ if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} \
-Wall \
-Winit-self \
-ggdb \
-Winit-self \
-ggdb \
-Wextra \
-Wcast-align \
-Wcast-qual \
@ -25,6 +25,7 @@ if (CMAKE_COMPILER_IS_GNUCXX)
-Wsign-promo")
else ()
set(CMAKE_CXX_FLAGS "/EHsc")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:10000000")
endif (CMAKE_COMPILER_IS_GNUCXX)
IF (WIN32)

View file

@ -1,4 +1,5 @@
add_library(common_util
SHARED
FileUtil.cpp
DgoWriter.cpp
Timer.cpp)

28
common/util/DgoWriter.cpp Normal file
View file

@ -0,0 +1,28 @@
#include "BinaryWriter.h"
#include "FileUtil.h"
#include "DgoWriter.h"
void build_dgo(const DgoDescription& description) {
BinaryWriter writer;
// dgo header
writer.add<uint32_t>(description.entries.size());
writer.add_cstr_len(description.dgo_name.c_str(), 60);
for (auto& obj : description.entries) {
auto obj_data = file_util::read_binary_file(file_util::get_file_path({"data", obj.file_name}));
// size
writer.add<uint32_t>(obj_data.size());
// name
writer.add_str_len(obj.name_in_dgo, 60);
// data
writer.add_data(obj_data.data(), obj_data.size());
// pad
while (writer.get_size() & 0xf) {
writer.add<uint8_t>(0);
}
}
printf("DGO: %15s %.3f MB\n", description.dgo_name.c_str(),
(float)(writer.get_size()) / (1 << 20));
writer.write_to_file(file_util::get_file_path({"out", description.dgo_name}));
}

17
common/util/DgoWriter.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef JAK_DGOWRITER_H
#define JAK_DGOWRITER_H
#include <vector>
struct DgoDescription {
std::string dgo_name;
struct DgoEntry {
std::string file_name;
std::string name_in_dgo;
};
std::vector<DgoEntry> entries;
};
void build_dgo(const DgoDescription& description);
#endif // JAK_DGOWRITER_H

View file

@ -9,26 +9,29 @@
#include <Windows.h>
#else
#include <unistd.h>
#include <cstring>
#endif
std::string file_util::get_project_path() {
#ifdef _WIN32
char buffer[FILENAME_MAX];
GetModuleFileNameA(NULL, buffer, FILENAME_MAX);
std::string::size_type pos = std::string(buffer).rfind(
"\\jak-project\\"); // Strip file path down to \jak-project\ directory
printf("using path %s\n", buffer);
std::string::size_type pos =
std::string(buffer).rfind("jak-project"); // Strip file path down to \jak-project\ directory
printf("rfind returned %lld\n", pos);
return std::string(buffer).substr(
0, pos + 12); // + 12 to include "\jak-project" in the returned filepath
0, pos + 11); // + 12 to include "\jak-project" in the returned filepath
#else
// do Linux stuff
char buffer[FILENAME_MAX];
readlink("/proc/self/exe", buffer,
FILENAME_MAX); // /proc/self acts like a "virtual folder" containing information about
// the current process
std::string::size_type pos = std::string(buffer).rfind(
"/jak-project/"); // Strip file path down to /jak-project/ directory
std::string::size_type pos =
std::string(buffer).rfind("jak-project"); // Strip file path down to /jak-project/ directory
return std::string(buffer).substr(
0, pos + 12); // + 12 to include "/jak-project" in the returned filepath
0, pos + 11); // + 12 to include "/jak-project" in the returned filepath
#endif
}
@ -76,7 +79,8 @@ void file_util::write_text_file(const std::string& file_name, const std::string&
std::vector<uint8_t> file_util::read_binary_file(const std::string& filename) {
auto fp = fopen(filename.c_str(), "rb");
if (!fp)
throw std::runtime_error("File " + filename + " cannot be opened");
throw std::runtime_error("File " + filename +
" cannot be opened: " + std::string(strerror(errno)));
fseek(fp, 0, SEEK_END);
auto len = ftell(fp);
rewind(fp);
@ -87,6 +91,7 @@ std::vector<uint8_t> file_util::read_binary_file(const std::string& filename) {
if (fread(data.data(), len, 1, fp) != 1) {
throw std::runtime_error("File " + filename + " cannot be read");
}
fclose(fp);
return data;
}

View file

@ -1,5 +1,5 @@
# We define our own compilation flags here.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 14)
# Set default compile flags for GCC
# optimization level can be set here. Note that game/ overwrites this for building game C++ code.

View file

@ -2,8 +2,8 @@
; Each entry should consist of an ISO name, followed by a file name
; note that tweakval, vagdir, screen1 have dummy data for now.
KERNEL.CGO resources/KERNEL.CGO
GAME.CGO resources/GAME.CGO
KERNEL.CGO out/KERNEL.CGO
GAME.CGO out/GAME.CGO
TEST.CGO resources/TEST.CGO
TWEAKVAL.MUS resources/TWEAKVAL.MUS
VAGDIR.AYB resources/VAGDIR.AYB

View file

@ -149,6 +149,7 @@ void ProcessListenerMessage(Ptr<char> msg) {
// this setup allows listener function execution to clean up after itself.
ListenerFunction->value =
link_and_exec(buffer, "*listener*", 0, kdebugheap, LINK_FLAG_FORCE_DEBUG).offset;
fprintf(stderr, "ListenerFunction is now 0x%x\n", ListenerFunction->value);
return; // don't ack yet, this will happen after the function runs.
} break;
default:

511
goal_src/build/all_files.gc Normal file
View file

@ -0,0 +1,511 @@
(defglobalconstant all-goal-files
(
"goal_src/kernel/gcommon.gc"
"goal_src/kernel/gstring-h.gc"
"goal_src/kernel/gkernel-h.gc"
"goal_src/kernel/gkernel.gc"
"goal_src/kernel/pskernel.gc"
"goal_src/kernel/gstring.gc"
"goal_src/kernel/dgo-h.gc"
"goal_src/kernel/gstate.gc"
"goal_src/engine/util/types-h.gc"
"goal_src/engine/ps2/vu1-macros.gc"
"goal_src/engine/math/math.gc"
"goal_src/engine/math/vector-h.gc"
"goal_src/engine/physics/gravity-h.gc"
"goal_src/engine/geometry/bounding-box-h.gc"
"goal_src/engine/math/matrix-h.gc"
"goal_src/engine/math/quaternion-h.gc"
"goal_src/engine/math/euler-h.gc"
"goal_src/engine/math/transform-h.gc"
"goal_src/engine/geometry/geometry-h.gc"
"goal_src/engine/math/trigonometry-h.gc"
"goal_src/engine/math/transformq-h.gc"
"goal_src/engine/geometry/bounding-box.gc"
"goal_src/engine/math/matrix.gc"
"goal_src/engine/math/transform.gc"
"goal_src/engine/math/quaternion.gc"
"goal_src/engine/math/euler.gc"
"goal_src/engine/geometry/geometry.gc"
"goal_src/engine/math/trigonometry.gc"
"goal_src/engine/sound/gsound-h.gc"
"goal_src/engine/ps2/timer-h.gc"
"goal_src/engine/ps2/timer.gc"
"goal_src/engine/ps2/vif-h.gc"
"goal_src/engine/dma/dma-h.gc"
"goal_src/engine/gfx/hw/video-h.gc"
"goal_src/engine/gfx/hw/vu1-user-h.gc"
"goal_src/engine/dma/dma.gc"
"goal_src/engine/dma/dma-buffer.gc"
"goal_src/engine/dma/dma-bucket.gc"
"goal_src/engine/dma/dma-disasm.gc"
"goal_src/engine/ps2/pad.gc"
"goal_src/engine/gfx/hw/gs.gc"
"goal_src/engine/gfx/hw/display-h.gc"
"goal_src/engine/math/vector.gc"
"goal_src/engine/load/file-io.gc"
"goal_src/engine/load/loader-h.gc"
"goal_src/engine/gfx/texture-h.gc"
"goal_src/engine/level/level-h.gc"
"goal_src/engine/camera/math-camera-h.gc"
"goal_src/engine/camera/math-camera.gc"
"goal_src/engine/gfx/font-h.gc"
"goal_src/engine/gfx/decomp-h.gc"
"goal_src/engine/gfx/hw/display.gc"
"goal_src/engine/engine/connect.gc"
"goal_src/engine/ui/text-h.gc"
"goal_src/engine/game/settings-h.gc"
"goal_src/engine/gfx/capture.gc"
"goal_src/engine/debug/memory-usage-h.gc"
"goal_src/engine/gfx/texture.gc"
"goal_src/engine/game/main-h.gc"
"goal_src/engine/anim/mspace-h.gc"
"goal_src/engine/draw/drawable-h.gc"
"goal_src/engine/draw/drawable-group-h.gc"
"goal_src/engine/draw/drawable-inline-array-h.gc"
"goal_src/engine/draw/draw-node-h.gc"
"goal_src/engine/draw/drawable-tree-h.gc"
"goal_src/engine/draw/drawable-actor-h.gc"
"goal_src/engine/draw/drawable-ambient-h.gc"
"goal_src/engine/game/task/game-task-h.gc"
"goal_src/engine/game/task/hint-control-h.gc"
"goal_src/engine/gfx/generic/generic-h.gc"
"goal_src/engine/gfx/lights-h.gc"
"goal_src/engine/gfx/ocean/ocean-h.gc"
"goal_src/engine/gfx/ocean/ocean-trans-tables.gc"
"goal_src/engine/gfx/ocean/ocean-tables.gc"
"goal_src/engine/gfx/ocean/ocean-frames.gc"
"goal_src/engine/gfx/sky/sky-h.gc"
"goal_src/engine/gfx/mood-h.gc"
"goal_src/engine/gfx/time-of-day-h.gc"
"goal_src/engine/data/art-h.gc"
"goal_src/engine/gfx/generic/generic-vu1-h.gc"
"goal_src/engine/gfx/merc/merc-h.gc"
"goal_src/engine/gfx/merc/generic-merc-h.gc"
"goal_src/engine/gfx/tie/generic-tie-h.gc"
"goal_src/engine/gfx/generic/generic-work-h.gc"
"goal_src/engine/gfx/shadow/shadow-cpu-h.gc"
"goal_src/engine/gfx/shadow/shadow-vu1-h.gc"
"goal_src/engine/ps2/memcard-h.gc"
"goal_src/engine/game/game-info-h.gc"
"goal_src/engine/gfx/wind-h.gc"
"goal_src/engine/gfx/tie/prototype-h.gc"
"goal_src/engine/anim/joint-h.gc"
"goal_src/engine/anim/bones-h.gc"
"goal_src/engine/engine/engines.gc"
"goal_src/engine/data/res-h.gc"
"goal_src/engine/data/res.gc"
"goal_src/engine/gfx/lights.gc"
"goal_src/engine/physics/dynamics-h.gc"
"goal_src/engine/target/surface-h.gc"
"goal_src/engine/target/pat-h.gc"
"goal_src/engine/game/fact-h.gc"
"goal_src/engine/anim/aligner-h.gc"
"goal_src/engine/game/game-h.gc"
"goal_src/engine/game/generic-obs-h.gc"
"goal_src/engine/camera/pov-camera-h.gc"
"goal_src/engine/util/sync-info-h.gc"
"goal_src/engine/util/smush-control-h.gc"
"goal_src/engine/physics/trajectory-h.gc"
"goal_src/engine/debug/debug-h.gc"
"goal_src/engine/target/joint-mod-h.gc"
"goal_src/engine/collide/collide-func-h.gc"
"goal_src/engine/collide/collide-mesh-h.gc"
"goal_src/engine/collide/collide-shape-h.gc"
"goal_src/engine/collide/collide-target-h.gc"
"goal_src/engine/collide/collide-touch-h.gc"
"goal_src/engine/collide/collide-edge-grab-h.gc"
"goal_src/engine/draw/process-drawable-h.gc"
"goal_src/engine/game/effect-control-h.gc"
"goal_src/engine/collide/collide-frag-h.gc"
"goal_src/engine/game/projectiles-h.gc"
"goal_src/engine/target/target-h.gc"
"goal_src/engine/gfx/depth-cue-h.gc"
"goal_src/engine/debug/stats-h.gc"
"goal_src/engine/gfx/vis/bsp-h.gc"
"goal_src/engine/collide/collide-cache-h.gc"
"goal_src/engine/collide/collide-h.gc"
"goal_src/engine/gfx/shrub/shrubbery-h.gc"
"goal_src/engine/gfx/tie/tie-h.gc"
"goal_src/engine/gfx/tfrag/tfrag-h.gc"
"goal_src/engine/gfx/background-h.gc"
"goal_src/engine/gfx/tfrag/subdivide-h.gc"
"goal_src/engine/entity/entity-h.gc"
"goal_src/engine/gfx/sprite/sprite-h.gc"
"goal_src/engine/gfx/shadow/shadow-h.gc"
"goal_src/engine/gfx/eye-h.gc"
"goal_src/engine/sparticle/sparticle-launcher-h.gc"
"goal_src/engine/sparticle/sparticle-h.gc"
"goal_src/engine/entity/actor-link-h.gc"
"goal_src/engine/camera/camera-h.gc"
"goal_src/engine/camera/cam-debug-h.gc"
"goal_src/engine/camera/cam-interface-h.gc"
"goal_src/engine/camera/cam-update-h.gc"
"goal_src/engine/debug/assert-h.gc"
"goal_src/engine/ui/hud-h.gc"
"goal_src/engine/ui/progress-h.gc"
"goal_src/engine/ps2/rpc-h.gc"
"goal_src/engine/nav/path-h.gc"
"goal_src/engine/nav/navigate-h.gc"
"goal_src/engine/load/load-dgo.gc"
"goal_src/engine/load/ramdisk.gc"
"goal_src/engine/sound/gsound.gc"
"goal_src/engine/math/transformq.gc"
"goal_src/engine/collide/collide-func.gc"
"goal_src/engine/anim/joint.gc"
"goal_src/engine/geometry/cylinder.gc"
"goal_src/engine/gfx/wind.gc"
"goal_src/engine/gfx/vis/bsp.gc"
"goal_src/engine/gfx/tfrag/subdivide.gc"
"goal_src/engine/gfx/sprite/sprite.gc"
"goal_src/engine/gfx/sprite/sprite-distort.gc"
"goal_src/engine/debug/debug-sphere.gc"
"goal_src/engine/debug/debug.gc"
"goal_src/engine/gfx/merc/merc-vu1.gc"
"goal_src/engine/gfx/merc/merc-blend-shape.gc"
"goal_src/engine/gfx/merc/merc.gc"
"goal_src/engine/gfx/ripple.gc"
"goal_src/engine/anim/bones.gc"
"goal_src/engine/gfx/generic/generic-vu0.gc"
"goal_src/engine/gfx/generic/generic.gc"
"goal_src/engine/gfx/generic/generic-vu1.gc"
"goal_src/engine/gfx/generic/generic-effect.gc"
"goal_src/engine/gfx/generic/generic-merc.gc"
"goal_src/engine/gfx/generic/generic-tie.gc"
"goal_src/engine/gfx/shadow/shadow-cpu.gc"
"goal_src/engine/gfx/shadow/shadow-vu1.gc"
"goal_src/engine/gfx/depth-cue.gc"
"goal_src/engine/gfx/font.gc"
"goal_src/engine/load/decomp.gc"
"goal_src/engine/gfx/background.gc"
"goal_src/engine/draw/draw-node.gc"
"goal_src/engine/gfx/shrub/shrubbery.gc"
"goal_src/engine/gfx/shrub/shrub-work.gc"
"goal_src/engine/gfx/tfrag/tfrag-near.gc"
"goal_src/engine/gfx/tfrag/tfrag.gc"
"goal_src/engine/gfx/tfrag/tfrag-methods.gc"
"goal_src/engine/gfx/tfrag/tfrag-work.gc"
"goal_src/engine/gfx/tie/tie.gc"
"goal_src/engine/gfx/tie/tie-near.gc"
"goal_src/engine/gfx/tie/tie-work.gc"
"goal_src/engine/gfx/tie/tie-methods.gc"
"goal_src/engine/util/sync-info.gc"
"goal_src/engine/physics/trajectory.gc"
"goal_src/engine/sparticle/sparticle-launcher.gc"
"goal_src/engine/sparticle/sparticle.gc"
"goal_src/engine/entity/entity-table.gc"
"goal_src/engine/load/loader.gc"
"goal_src/engine/game/task/task-control-h.gc"
"goal_src/engine/game/game-info.gc"
"goal_src/engine/game/game-save.gc"
"goal_src/engine/game/settings.gc"
"goal_src/engine/ambient/mood-tables.gc"
"goal_src/engine/ambient/mood.gc"
"goal_src/engine/ambient/weather-part.gc"
"goal_src/engine/gfx/time-of-day.gc"
"goal_src/engine/gfx/sky/sky-utils.gc"
"goal_src/engine/gfx/sky/sky.gc"
"goal_src/engine/gfx/sky/sky-tng.gc"
"goal_src/engine/level/load-boundary-h.gc"
"goal_src/engine/level/load-boundary.gc"
"goal_src/engine/level/load-boundary-data.gc"
"goal_src/engine/level/level-info.gc"
"goal_src/engine/level/level.gc"
"goal_src/engine/ui/text.gc"
"goal_src/engine/collide/collide-probe.gc"
"goal_src/engine/collide/collide-frag.gc"
"goal_src/engine/collide/collide-mesh.gc"
"goal_src/engine/collide/collide-touch.gc"
"goal_src/engine/collide/collide-edge-grab.gc"
"goal_src/engine/collide/collide-shape.gc"
"goal_src/engine/collide/collide-shape-rider.gc"
"goal_src/engine/collide/collide.gc"
"goal_src/engine/collide/collide-planes.gc"
"goal_src/engine/gfx/merc/merc-death.gc"
"goal_src/engine/gfx/water/water-h.gc"
"goal_src/engine/camera/camera.gc"
"goal_src/engine/camera/cam-interface.gc"
"goal_src/engine/camera/cam-master.gc"
"goal_src/engine/camera/cam-states.gc"
"goal_src/engine/camera/cam-states-dbg.gc"
"goal_src/engine/camera/cam-combiner.gc"
"goal_src/engine/camera/cam-update.gc"
"goal_src/engine/geometry/vol-h.gc"
"goal_src/engine/camera/cam-layout.gc"
"goal_src/engine/camera/cam-debug.gc"
"goal_src/engine/camera/cam-start.gc"
"goal_src/engine/draw/process-drawable.gc"
"goal_src/engine/game/task/hint-control.gc"
"goal_src/engine/ambient/ambient.gc"
"goal_src/engine/debug/assert.gc"
"goal_src/engine/game/generic-obs.gc"
"goal_src/engine/target/target-util.gc"
"goal_src/engine/target/target-part.gc"
"goal_src/engine/collide/collide-reaction-target.gc"
"goal_src/engine/target/logic-target.gc"
"goal_src/engine/target/sidekick.gc"
"goal_src/engine/game/voicebox.gc"
"goal_src/engine/target/target-handler.gc"
"goal_src/engine/target/target.gc"
"goal_src/engine/target/target2.gc"
"goal_src/engine/target/target-death.gc"
"goal_src/engine/debug/menu.gc"
"goal_src/engine/draw/drawable.gc"
"goal_src/engine/draw/drawable-group.gc"
"goal_src/engine/draw/drawable-inline-array.gc"
"goal_src/engine/draw/drawable-tree.gc"
"goal_src/engine/gfx/tie/prototype.gc"
"goal_src/engine/collide/main-collide.gc"
"goal_src/engine/game/video.gc"
"goal_src/engine/game/main.gc"
"goal_src/engine/collide/collide-cache.gc"
"goal_src/engine/entity/relocate.gc"
"goal_src/engine/debug/memory-usage.gc"
"goal_src/engine/entity/entity.gc"
"goal_src/engine/nav/path.gc"
"goal_src/engine/geometry/vol.gc"
"goal_src/engine/nav/navigate.gc"
"goal_src/engine/anim/aligner.gc"
"goal_src/engine/game/effect-control.gc"
"goal_src/engine/gfx/water/water.gc"
"goal_src/engine/game/collectables-part.gc"
"goal_src/engine/game/collectables.gc"
"goal_src/engine/game/task/task-control.gc"
"goal_src/engine/game/task/process-taskable.gc"
"goal_src/engine/camera/pov-camera.gc"
"goal_src/engine/game/powerups.gc"
"goal_src/engine/game/crates.gc"
"goal_src/engine/ui/hud.gc"
"goal_src/engine/ui/hud-classes.gc"
"goal_src/engine/ui/progress/progress-static.gc"
"goal_src/engine/ui/progress/progress-part.gc"
"goal_src/engine/ui/progress/progress-draw.gc"
"goal_src/engine/ui/progress/progress.gc"
"goal_src/engine/ui/credits.gc"
"goal_src/engine/game/projectiles.gc"
"goal_src/engine/gfx/ocean/ocean.gc"
"goal_src/engine/gfx/ocean/ocean-vu0.gc"
"goal_src/engine/gfx/ocean/ocean-texture.gc"
"goal_src/engine/gfx/ocean/ocean-mid.gc"
"goal_src/engine/gfx/ocean/ocean-transition.gc"
"goal_src/engine/gfx/ocean/ocean-near.gc"
"goal_src/engine/gfx/shadow/shadow.gc"
"goal_src/engine/gfx/eye.gc"
"goal_src/engine/util/glist-h.gc"
"goal_src/engine/util/glist.gc"
"goal_src/engine/debug/anim-tester.gc"
"goal_src/engine/debug/viewer.gc"
"goal_src/engine/debug/part-tester.gc"
"goal_src/engine/debug/default-menu.gc"
"goal_src/levels/common/texture-upload.gc"
"goal_src/levels/common/rigid-body-h.gc"
"goal_src/levels/common/water-anim.gc"
"goal_src/levels/common/dark-eco-pool.gc"
"goal_src/levels/common/rigid-body.gc"
"goal_src/levels/common/nav-enemy-h.gc"
"goal_src/levels/common/nav-enemy.gc"
"goal_src/levels/common/baseplat.gc"
"goal_src/levels/common/basebutton.gc"
"goal_src/levels/common/tippy.gc"
"goal_src/levels/common/joint-exploder.gc"
"goal_src/levels/common/babak.gc"
"goal_src/levels/common/sharkey.gc"
"goal_src/levels/common/orb-cache.gc"
"goal_src/levels/common/plat.gc"
"goal_src/levels/common/plat-button.gc"
"goal_src/levels/common/plat-eco.gc"
"goal_src/levels/common/ropebridge.gc"
"goal_src/levels/common/ticky.gc"
"goal_src/levels/common/mistycannon.gc"
"goal_src/levels/common/babak-with-cannon.gc"
"goal_src/levels/beach/air-h.gc"
"goal_src/levels/beach/air.gc"
"goal_src/levels/beach/wobbler.gc"
"goal_src/levels/beach/twister.gc"
"goal_src/levels/beach/beach-obs.gc"
"goal_src/levels/beach/bird-lady.gc"
"goal_src/levels/beach/bird-lady-beach.gc"
"goal_src/levels/beach/mayor.gc"
"goal_src/levels/beach/sculptor.gc"
"goal_src/levels/beach/pelican.gc"
"goal_src/levels/beach/lurkerworm.gc"
"goal_src/levels/beach/lurkercrab.gc"
"goal_src/levels/beach/lurkerpuppy.gc"
"goal_src/levels/beach/beach-rocks.gc"
"goal_src/levels/beach/seagull.gc"
"goal_src/levels/beach/beach-part.gc"
"goal_src/levels/village_common/villagep-obs.gc"
"goal_src/levels/village_common/oracle.gc"
"goal_src/levels/common/battlecontroller.gc"
"goal_src/levels/citadel/citadel-part.gc"
"goal_src/levels/citadel/citadel-obs.gc"
"goal_src/levels/citadel/citb-plat.gc"
"goal_src/levels/citadel/citadel-sages.gc"
"goal_src/levels/common/snow-bunny.gc"
"goal_src/levels/citadel/citb-bunny.gc"
"goal_src/levels/citadel/citb-drop-plat-CIT.gc"
"goal_src/levels/l1_only/citb-drop-plat-L1.gc"
"goal_src/levels/citadel/assistant-citadel.gc"
"goal_src/levels/darkcave/darkcave-obs.gc"
"goal_src/levels/demo/demo-obs.gc"
"goal_src/levels/common/static-screen.gc"
"goal_src/levels/finalboss/robotboss-h.gc"
"goal_src/levels/finalboss/robotboss-part.gc"
"goal_src/levels/finalboss/sage-finalboss-part.gc"
"goal_src/levels/finalboss/light-eco.gc"
"goal_src/levels/finalboss/robotboss-weapon.gc"
"goal_src/levels/finalboss/robotboss-misc.gc"
"goal_src/levels/finalboss/green-eco-lurker.gc"
"goal_src/levels/finalboss/robotboss.gc"
"goal_src/levels/finalboss/final-door.gc"
"goal_src/levels/finalboss/sage-finalboss-FIN.gc"
"goal_src/levels/l1_only/sage-finalboss-L1.gc"
"goal_src/levels/intro/evilbro.gc"
"goal_src/levels/jungleb/jungleb-obs.gc"
"goal_src/levels/jungleb/plat-flip.gc"
"goal_src/levels/jungleb/aphid.gc"
"goal_src/levels/jungleb/plant-boss.gc"
"goal_src/levels/jungle/jungle-elevator.gc"
"goal_src/levels/jungle/bouncer.gc"
"goal_src/levels/jungle/hopper.gc"
"goal_src/levels/jungle/junglesnake.gc"
"goal_src/levels/jungle/darkvine.gc"
"goal_src/levels/jungle/jungle-obs.gc"
"goal_src/levels/jungle/jungle-mirrors.gc"
"goal_src/levels/jungle/junglefish.gc"
"goal_src/levels/jungle/fisher-JUN.gc"
"goal_src/levels/jungle/fisher-JUNGLE-L1.gc"
"goal_src/levels/jungle/jungle-part.gc"
"goal_src/levels/common/launcherdoor.gc"
"goal_src/levels/l1_only/target-racer-h-L1-RACERP.gc"
"goal_src/levels/racer_common/target-racer-h-FIC-LAV-MIS-OGR-ROL.gc"
"goal_src/levels/racer_common/racer-part.gc"
"goal_src/levels/racer_common/racer.gc"
"goal_src/levels/l1_only/target-racer-L1-RACERP.gc"
"goal_src/levels/racer_common/target-racer-FIC-LAV-MIS-OGR-ROL.gc"
"goal_src/levels/l1_only/racer-states-L1-RACERP.gc"
"goal_src/levels/racer_common/racer-states-FIC-LAV-MIS-OGR-ROL.gc"
"goal_src/levels/racer_common/collide-reaction-racer.gc"
"goal_src/levels/common/blocking-plane.gc"
"goal_src/levels/flut_common/flut-part.gc"
"goal_src/levels/flut_common/flutflut.gc"
"goal_src/levels/flut_common/target-flut.gc"
"goal_src/levels/village1/farmer.gc"
"goal_src/levels/village1/explorer.gc"
"goal_src/levels/village1/assistant.gc"
"goal_src/levels/village1/sage.gc"
"goal_src/levels/village1/yakow.gc"
"goal_src/levels/l1_only/village-obs-L1.gc"
"goal_src/levels/village1/village-obs-VI1.gc"
"goal_src/levels/village1/fishermans-boat.gc"
"goal_src/levels/village1/village1-part.gc"
"goal_src/levels/village1/village1-part2.gc"
"goal_src/levels/village1/sequence-a-village1.gc"
"goal_src/levels/training/training-obs.gc"
"goal_src/levels/training/training-part.gc"
"goal_src/levels/misty/misty-obs.gc"
"goal_src/levels/misty/misty-warehouse.gc"
"goal_src/levels/misty/misty-conveyor.gc"
"goal_src/levels/misty/mud.gc"
"goal_src/levels/misty/muse.gc"
"goal_src/levels/misty/bonelurker.gc"
"goal_src/levels/misty/quicksandlurker.gc"
"goal_src/levels/misty/misty-teetertotter.gc"
"goal_src/levels/misty/balloonlurker.gc"
"goal_src/levels/misty/misty-part.gc"
"goal_src/levels/misty/sidekick-human.gc"
"goal_src/levels/firecanyon/firecanyon-part.gc"
"goal_src/levels/firecanyon/assistant-firecanyon.gc"
"goal_src/levels/village2/village2-part.gc"
"goal_src/levels/village2/village2-obs.gc"
"goal_src/levels/village2/village2-part2.gc"
"goal_src/levels/village2/gambler.gc"
"goal_src/levels/village2/warrior.gc"
"goal_src/levels/village2/geologist.gc"
"goal_src/levels/village2/swamp-blimp.gc"
"goal_src/levels/village2/sage-bluehut.gc"
"goal_src/levels/village2/flutflut-bluehut.gc"
"goal_src/levels/village2/assistant-village2.gc"
"goal_src/levels/village2/sunken-elevator.gc"
"goal_src/levels/swamp/swamp-obs.gc"
"goal_src/levels/swamp/swamp-bat.gc"
"goal_src/levels/swamp/swamp-rat.gc"
"goal_src/levels/swamp/swamp-rat-nest.gc"
"goal_src/levels/swamp/kermit.gc"
"goal_src/levels/swamp/swamp-part.gc"
"goal_src/levels/swamp/billy.gc"
"goal_src/levels/maincave/cavecrystal-light.gc"
"goal_src/levels/maincave/maincave-obs.gc"
"goal_src/levels/maincave/maincave-part.gc"
"goal_src/levels/maincave/spiderwebs.gc"
"goal_src/levels/maincave/dark-crystal.gc"
"goal_src/levels/maincave/baby-spider.gc"
"goal_src/levels/maincave/mother-spider-h.gc"
"goal_src/levels/maincave/mother-spider-egg.gc"
"goal_src/levels/maincave/mother-spider-proj.gc"
"goal_src/levels/maincave/mother-spider.gc"
"goal_src/levels/maincave/gnawer.gc"
"goal_src/levels/maincave/driller-lurker.gc"
"goal_src/levels/sunken/sunken-part.gc"
"goal_src/levels/sunken/sunken-part2.gc"
"goal_src/levels/sunken/sunken-part3.gc"
"goal_src/levels/sunken/sunken-part4.gc"
"goal_src/levels/sunken/sunken-part5.gc"
"goal_src/levels/sunken/target-tube.gc"
"goal_src/levels/sunken/sunken-obs.gc"
"goal_src/levels/sunken/shover.gc"
"goal_src/levels/sunken/square-platform.gc"
"goal_src/levels/sunken/sun-iris-door.gc"
"goal_src/levels/sunken/orbit-plat.gc"
"goal_src/levels/sunken/wedge-plats.gc"
"goal_src/levels/sunken/wall-plat.gc"
"goal_src/levels/sunken/qbert-plat.gc"
"goal_src/levels/sunken/steam-cap.gc"
"goal_src/levels/sunken/sun-exit-chamber.gc"
"goal_src/levels/sunken/floating-launcher.gc"
"goal_src/levels/sunken/sunken-water.gc"
"goal_src/levels/sunken/whirlpool.gc"
"goal_src/levels/sunken/sunken-pipegame.gc"
"goal_src/levels/sunken/bully.gc"
"goal_src/levels/sunken/double-lurker.gc"
"goal_src/levels/sunken/helix-water.gc"
"goal_src/levels/sunken/puffer.gc"
"goal_src/levels/sunken/sunken-fish.gc"
"goal_src/levels/rolling/rolling-obs.gc"
"goal_src/levels/rolling/rolling-lightning-mole.gc"
"goal_src/levels/rolling/rolling-robber.gc"
"goal_src/levels/rolling/rolling-race-ring.gc"
"goal_src/levels/firecanyon/firecanyon-obs.gc"
"goal_src/levels/ogre/ogre-part.gc"
"goal_src/levels/ogre/ogreboss.gc"
"goal_src/levels/ogre/ogre-obs.gc"
"goal_src/levels/ogre/flying-lurker.gc"
"goal_src/levels/village3/village3-part.gc"
"goal_src/levels/village3/village3-obs.gc"
"goal_src/levels/village3/minecart.gc"
"goal_src/levels/village3/miners.gc"
"goal_src/levels/village3/assistant-village3.gc"
"goal_src/levels/village3/sage-village3.gc"
"goal_src/levels/robocave/cave-trap.gc"
"goal_src/levels/robocave/spider-egg.gc"
"goal_src/levels/robocave/robocave-part.gc"
"goal_src/levels/snow/target-snowball.gc"
"goal_src/levels/snow/target-ice.gc"
"goal_src/levels/snow/ice-cube.gc"
"goal_src/levels/snow/snow-ball.gc"
"goal_src/levels/snow/snow-obs.gc"
"goal_src/levels/snow/snow-flutflut-obs.gc"
"goal_src/levels/snow/snow-bumper.gc"
"goal_src/levels/snow/snow-ram-h.gc"
"goal_src/levels/snow/snow-ram-boss.gc"
"goal_src/levels/snow/snow-ram.gc"
"goal_src/levels/snow/snow-part.gc"
"goal_src/levels/snow/yeti.gc"
"goal_src/levels/lavatube/lavatube-obs.gc"
"goal_src/levels/lavatube/lavatube-energy.gc"
"goal_src/levels/lavatube/lavatube-part.gc"
"goal_src/levels/lavatube/assistant-lavatube.gc"
"goal_src/levels/title/title-obs.gc"
"goal_src/old/lava/lava.gc"
)
)

View file

@ -1,3 +1,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; BUILD SYSTEM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; compile, color, and save a file
(defmacro m (file)
`(asm-file ,file :color :write)
@ -8,6 +12,20 @@
`(asm-file ,file :color :load :write)
)
(desfun make-build-command (file)
`(asm-file ,file :color :write)
)
(defmacro build-game ()
`(begin
,@(apply make-build-command all-goal-files)
(build-dgos "goal_src/build/dgos.txt")
)
)
;; load list of all goal files
(asm-file "goal_src/build/all_files.gc")
(defmacro e ()
`(:exit)
)

View file

@ -0,0 +1,16 @@
(defun return-one ()
1)
(defun return-sum ((a integer) (b integer))
(+ a b)
)
(defun return-plus-two ((in integer))
(+ in 2)
)
(defun return-plus-three ((in integer))
(+ 3 in)
)
(+ 2 (return-one) (return-plus-three 2) (return-plus-two 3) (return-sum 1 2) (return-plus-two 3))

View file

@ -0,0 +1 @@
(+ 15 -2)

View file

@ -0,0 +1,11 @@
(defun add-five-v2 ((a int32) (b int32) (c int32) (d int32) (e int32))
(let* ((total-1 a)
(also-d d)
(total-2 (+ total-1 b))
(total-3 (+ c total-2))
)
(+ total-3 e also-d)
)
)
(add-five 1 2 3 4 5)

View file

@ -0,0 +1,5 @@
(defun add-five ((a integer) (b integer) (c integer) (d integer) (e integer))
(+ c d (+ e a) b)
)
(add-five 1 2 3 4 5)

View file

@ -0,0 +1,5 @@
(defun add-two ((x integer) (y integer))
(+ x y)
)
(add-two 3 4)

View file

@ -0,0 +1,6 @@
(build-game)
;(define-extern global kheap)
;(define-extern dgo-load (function string kheap int int int))
;(dgo-load "kernel" global #xf #x200000) ; todo, remove once kernel loads itself.
;(dgo-load "game" global #xf #x200000)
1

View file

@ -0,0 +1,5 @@
(defun product ((a integer) (b integer))
(* b a)
)
(product 4 -3)

View file

@ -0,0 +1,16 @@
(defun negative ((a integer))
(- a)
)
(defun minus-two ((a integer))
(- a 2)
)
(defun sub-test ((a integer) (b integer))
(- 1 a b)
)
(let ((x (sub-test 1 (minus-two 7))))
(- 1 x (- -2))
)

View file

@ -0,0 +1,17 @@
(defun negative ((a integer))
(- a)
)
(defun minus-two ((a integer))
(- a 2)
)
(defun sub-test ((a integer) (b integer))
(- 1 a b)
)
(let ((x (sub-test 1 (minus-two 7))))
(- 1 (negative -2) x)
)

View file

@ -18,6 +18,7 @@ add_library(compiler
compiler/compilation/CompilerControl.cpp
compiler/compilation/Block.cpp
compiler/compilation/Macro.cpp
compiler/compilation/Math.cpp
compiler/compilation/Define.cpp
compiler/compilation/Function.cpp
compiler/Util.cpp

View file

@ -86,13 +86,21 @@ void CodeGenerator::do_function(FunctionEnv* env, int f_idx) {
auto& bonus = allocs.stack_ops.at(ir_idx);
for (auto& op : bonus.ops) {
if (op.load) {
assert(false);
if (op.reg.is_gpr()) {
m_gen.add_instr(IGen::load64_gpr64_plus_s32(op.reg, op.slot * GPR_SIZE, RSP), i_rec);
} else {
assert(false);
}
}
}
ir->do_codegen(&m_gen, allocs, i_rec);
for (auto& op : bonus.ops) {
if (op.store) {
assert(false);
if (op.reg.is_gpr()) {
m_gen.add_instr(IGen::store64_gpr64_plus_s32(RSP, op.slot * GPR_SIZE, op.reg), i_rec);
} else {
assert(false);
}
}
}
}

View file

@ -158,6 +158,7 @@ void Compiler::color_object_file(FileEnv* env) {
input.debug_settings.print_input = true;
input.debug_settings.print_result = true;
input.debug_settings.print_analysis = true;
input.debug_settings.allocate_log_level = 2;
}
f->set_allocations(allocate_registers(input));
@ -186,6 +187,9 @@ std::vector<std::string> Compiler::run_test(const std::string& source_code) {
auto code = m_goos.reader.read_from_file({source_code});
auto compiled = compile_object_file("test-code", code, true);
if (compiled->is_empty()) {
return {};
}
color_object_file(compiled);
auto data = codegen_object_file(compiled);
m_listener.record_messages(ListenerMessageKind::MSG_PRINT);
@ -200,6 +204,12 @@ std::vector<std::string> Compiler::run_test(const std::string& source_code) {
}
}
std::vector<std::string> Compiler::run_test_no_load(const std::string& source_code) {
auto code = m_goos.reader.read_from_file({source_code});
auto compiled = compile_object_file("test-code", code, true);
return {};
}
void Compiler::shutdown_target() {
if (m_listener.is_connected()) {
m_listener.send_reset(true);

View file

@ -8,6 +8,8 @@
#include "goalc/compiler/IR.h"
#include "CompilerSettings.h"
enum MathMode { MATH_INT, MATH_BINT, MATH_FLOAT, MATH_INVALID };
class Compiler {
public:
Compiler();
@ -24,6 +26,7 @@ class Compiler {
None* get_none() { return m_none.get(); }
std::vector<std::string> run_test(const std::string& source_code);
std::vector<std::string> run_test_no_load(const std::string& source_code);
void shutdown_target();
private:
@ -83,6 +86,16 @@ class Compiler {
std::unordered_map<std::shared_ptr<goos::SymbolObject>, goos::Object> m_global_constants;
std::unordered_map<std::shared_ptr<goos::SymbolObject>, LambdaVal*> m_inlineable_functions;
CompilerSettings m_settings;
MathMode get_math_mode(const TypeSpec& ts);
bool is_number(const TypeSpec& ts);
bool is_float(const TypeSpec& ts);
bool is_integer(const TypeSpec& ts);
bool is_binteger(const TypeSpec& ts);
bool is_singed_integer_or_binteger(const TypeSpec& ts);
Val* number_to_integer(Val* in, Env* env);
Val* number_to_float(Val* in, Env* env);
Val* number_to_binteger(Val* in, Env* env);
Val* to_math_type(Val* in, MathMode mode, Env* env);
public:
// Atoms
@ -104,6 +117,8 @@ class Compiler {
Val* compile_poke(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_gs(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_set_config(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_in_package(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_build_dgo(const goos::Object& form, const goos::Object& rest, Env* env);
// Define
Val* compile_define(const goos::Object& form, const goos::Object& rest, Env* env);
@ -114,6 +129,11 @@ class Compiler {
Val* compile_quote(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_defglobalconstant(const goos::Object& form, const goos::Object& rest, Env* env);
// 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);
// Function
Val* compile_lambda(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_inline(const goos::Object& form, const goos::Object& rest, Env* env);

View file

@ -6,6 +6,9 @@ CompilerSettings::CompilerSettings() {
m_settings["print-regalloc"].kind = SettingKind::BOOL;
m_settings["print-regalloc"].boolp = &debug_print_regalloc;
m_settings["disable-math-const-prop"].kind = SettingKind::BOOL;
m_settings["disable-math-const-prop"].boolp = &disable_math_const_prop;
}
void CompilerSettings::set(const std::string& name, const goos::Object& value) {

View file

@ -10,6 +10,9 @@ class CompilerSettings {
CompilerSettings();
bool debug_print_ir = false;
bool debug_print_regalloc = false;
bool disable_math_const_prop = false;
bool emit_move_after_return = true;
void set(const std::string& name, const goos::Object& value);
private:

View file

@ -350,4 +350,56 @@ void IR_FunctionAddr::do_codegen(emitter::ObjectGenerator* gen,
auto instr = gen->add_instr(IGen::static_addr(dr, 0), irec);
gen->link_instruction_to_function(instr, gen->get_existing_function_record(m_src->idx_in_file));
gen->add_instr(IGen::sub_gpr64_gpr64(dr, emitter::gRegInfo.get_offset_reg()), irec);
}
/////////////////////
// IntegerMath
///////////////////
IR_IntegerMath::IR_IntegerMath(IntegerMathKind kind, RegVal* dest, RegVal* arg)
: m_kind(kind), m_dest(dest), m_arg(arg) {}
std::string IR_IntegerMath::print() {
switch (m_kind) {
case IntegerMathKind::ADD_64:
return fmt::format("addi {}, {}", m_dest->print(), m_arg->print());
case IntegerMathKind::SUB_64:
return fmt::format("subi {}, {}", m_dest->print(), m_arg->print());
case IntegerMathKind::IMUL_32:
return fmt::format("imul {}, {}", m_dest->print(), m_arg->print());
default:
assert(false);
}
}
RegAllocInstr IR_IntegerMath::to_rai() {
RegAllocInstr rai;
rai.write.push_back(m_dest->ireg());
rai.read.push_back(m_dest->ireg());
rai.read.push_back(m_arg->ireg());
return rai;
}
void IR_IntegerMath::do_codegen(emitter::ObjectGenerator* gen,
const AllocationResult& allocs,
emitter::IR_Record irec) {
switch (m_kind) {
case IntegerMathKind::ADD_64:
gen->add_instr(
IGen::add_gpr64_gpr64(get_reg(m_dest, allocs, irec), get_reg(m_arg, allocs, irec)), irec);
break;
case IntegerMathKind::SUB_64:
gen->add_instr(
IGen::sub_gpr64_gpr64(get_reg(m_dest, allocs, irec), get_reg(m_arg, allocs, irec)), irec);
break;
case IntegerMathKind::IMUL_32: {
auto dr = get_reg(m_dest, allocs, irec);
gen->add_instr(IGen::imul_gpr32_gpr32(dr, get_reg(m_arg, allocs, irec)), irec);
gen->add_instr(IGen::movsx_r64_r32(dr, dr), irec);
}
break;
default:
assert(false);
}
}

View file

@ -173,4 +173,37 @@ class IR_FunctionAddr : public IR {
FunctionEnv* m_src = nullptr;
};
enum class IntegerMathKind {
ADD_64,
SUB_64,
IMUL_32,
IDIV_32,
SHLV_64,
SARV_64,
SHRV_64,
SHL_64,
SAR_64,
SHR_64,
IMOD_32,
OR_64,
AND_64,
XOR_64,
NOT_64
};
class IR_IntegerMath : public IR {
public:
IR_IntegerMath(IntegerMathKind kind, RegVal* dest, RegVal* arg);
std::string print() override;
RegAllocInstr to_rai() override;
void do_codegen(emitter::ObjectGenerator* gen,
const AllocationResult& allocs,
emitter::IR_Record irec) override;
protected:
IntegerMathKind m_kind;
RegVal* m_dest;
RegVal* m_arg;
};
#endif // JAK_IR_H

View file

@ -131,13 +131,23 @@ class StaticVal : public Val {
class IntegerConstantVal : public Val {
public:
IntegerConstantVal(TypeSpec ts, s64 value) : Val(ts), m_value(value) {}
IntegerConstantVal(TypeSpec ts, s64 value) : Val(std::move(ts)), m_value(value) {}
std::string print() const override { return "integer-constant-" + std::to_string(m_value); }
RegVal* to_reg(Env* fe) override;
protected:
s64 m_value = -1;
};
class FloatConstantVal : public Val {
public:
FloatConstantVal(TypeSpec ts, float value) : Val(std::move(ts)), m_value(value) {}
std::string print() const override { return "float-constant-" + std::to_string(m_value); }
RegVal* to_reg(Env* fe) override;
protected:
float m_value = -1.f;
};
// IntegerConstant
// FloatConstant
// Bitfield

View file

@ -37,7 +37,7 @@ static const std::unordered_map<
{"reset-target", &Compiler::compile_reset_target},
{":status", &Compiler::compile_poke},
// {"test", &Compiler::compile_test},
// {"in-package", &Compiler::compile_in_package},
{"in-package", &Compiler::compile_in_package},
//
// // CONDITIONAL COMPILATION
{"#cond", &Compiler::compile_gscond},
@ -102,9 +102,9 @@ static const std::unordered_map<
// {"cdr", &Compiler::compile_cdr},
//
// // IT IS MATH
// {"+", &Compiler::compile_add},
// {"-", &Compiler::compile_sub},
// {"*", &Compiler::compile_mult},
{"+", &Compiler::compile_add},
{"-", &Compiler::compile_sub},
{"*", &Compiler::compile_mul},
// {"/", &Compiler::compile_divide},
// {"shlv", &Compiler::compile_shlv},
// {"shrv", &Compiler::compile_shrv},
@ -127,7 +127,7 @@ static const std::unordered_map<
// {">", &Compiler::compile_condition_as_bool},
//
// // BUILDER (build-dgo/build-cgo?)
// {"builder", &Compiler::compile_builder},
{"build-dgos", &Compiler::compile_build_dgo},
//
// // UTIL
{"set-config!", &Compiler::compile_set_config},

View file

@ -1,6 +1,7 @@
#include "goalc/compiler/Compiler.h"
#include "goalc/compiler/IR.h"
#include "common/util/Timer.h"
#include "common/util/DgoWriter.h"
#include "common/util/FileUtil.h"
Val* Compiler::compile_exit(const goos::Object& form, const goos::Object& rest, Env* env) {
@ -67,6 +68,7 @@ Val* Compiler::compile_asm_file(const goos::Object& form, const goos::Object& re
for (int idx = int(filename.size()) - 1; idx-- > 0;) {
if (filename.at(idx) == '\\' || filename.at(idx) == '/') {
obj_file_name = filename.substr(idx + 1);
break;
}
}
@ -94,7 +96,7 @@ Val* Compiler::compile_asm_file(const goos::Object& form, const goos::Object& re
if (write) {
// auto output_dir = as_string(get_constant_or_error(form, "*compiler-output-path*"));
// todo, change extension based on v3/v4
auto output_name = m_goos.reader.get_source_dir() + "/out/" + obj_file_name + ".o";
auto output_name = m_goos.reader.get_source_dir() + "/data/" + obj_file_name + ".o";
file_util::write_binary_file(output_name, (void*)data.data(), data.size());
}
} else {
@ -108,9 +110,11 @@ Val* Compiler::compile_asm_file(const goos::Object& form, const goos::Object& re
}
// if(truthy(get_config("print-asm-file-time"))) {
printf("F: %36s ", obj_file_name.c_str());
for (auto& e : timing) {
printf(" %12s %4.2f\n", e.first.c_str(), e.second);
printf(" %12s %4.2f", e.first.c_str(), e.second);
}
printf("\n");
// }
return get_none();
@ -181,5 +185,41 @@ Val* Compiler::compile_set_config(const goos::Object& form, const goos::Object&
auto args = get_va(form, rest);
va_check(form, args, {goos::ObjectType::SYMBOL, {}}, {});
m_settings.set(symbol_string(args.unnamed.at(0)), args.unnamed.at(1));
return get_none();
}
Val* Compiler::compile_in_package(const goos::Object& form, const goos::Object& rest, Env* env) {
(void)form;
(void)rest;
(void)env;
return get_none();
}
Val* Compiler::compile_build_dgo(const goos::Object& form, const goos::Object& rest, Env* env) {
(void)env;
auto args = get_va(form, rest);
va_check(form, args, {goos::ObjectType::STRING}, {});
auto dgo_desc = pair_cdr(m_goos.reader.read_from_file({args.unnamed.at(0).as_string()->data}));
for_each_in_list(dgo_desc, [&](const goos::Object& dgo) {
DgoDescription desc;
auto first = pair_car(dgo);
desc.dgo_name = as_string(first);
auto dgo_rest = pair_cdr(dgo);
for_each_in_list(dgo_rest, [&](const goos::Object& entry) {
auto e_arg = get_va(dgo, entry);
va_check(dgo, e_arg, {goos::ObjectType::STRING, goos::ObjectType::STRING}, {});
DgoDescription::DgoEntry o;
o.file_name = as_string(e_arg.unnamed.at(0));
o.name_in_dgo = as_string(e_arg.unnamed.at(1));
if (o.file_name.substr(o.file_name.length() - 3) != ".go") { // kill v2's for now.
desc.entries.push_back(o);
}
});
build_dgo(desc);
});
return get_none();
}

View file

@ -351,5 +351,12 @@ Val* Compiler::compile_real_function_call(const goos::Object& form,
}
env->emit(std::make_unique<IR_FunctionCall>(function, return_reg, arg_outs));
return return_reg;
if (m_settings.emit_move_after_return) {
auto result_reg = env->make_gpr(return_reg->type());
env->emit(std::make_unique<IR_RegSet>(result_reg, return_reg));
return result_reg;
} else {
return return_reg;
}
}

View file

@ -0,0 +1,203 @@
#include "goalc/compiler/Compiler.h"
MathMode Compiler::get_math_mode(const TypeSpec& ts) {
if (m_ts.typecheck(m_ts.make_typespec("binteger"), ts, "", false, false)) {
return MATH_BINT;
}
if (m_ts.typecheck(m_ts.make_typespec("integer"), ts, "", false, false)) {
return MATH_INT;
}
if (m_ts.typecheck(m_ts.make_typespec("float"), ts, "", false, false)) {
return MATH_FLOAT;
}
return MATH_INVALID;
}
bool Compiler::is_number(const TypeSpec& ts) {
return m_ts.typecheck(m_ts.make_typespec("number"), ts, "", false, false);
}
bool Compiler::is_float(const TypeSpec& ts) {
return m_ts.typecheck(m_ts.make_typespec("float"), ts, "", false, false);
}
bool Compiler::is_integer(const TypeSpec& ts) {
return m_ts.typecheck(m_ts.make_typespec("integer"), ts, "", false, false) &&
!m_ts.typecheck(m_ts.make_typespec("binteger"), ts, "", false, false);
}
bool Compiler::is_binteger(const TypeSpec& ts) {
return m_ts.typecheck(m_ts.make_typespec("binteger"), ts, "", false, false);
}
bool Compiler::is_singed_integer_or_binteger(const TypeSpec& ts) {
return m_ts.typecheck(m_ts.make_typespec("integer"), ts, "", false, false) &&
!m_ts.typecheck(m_ts.make_typespec("uinteger"), ts, "", false, false);
}
Val* Compiler::number_to_integer(Val* in, Env* env) {
auto ts = in->type();
if (is_binteger(ts)) {
assert(false);
} else if (is_float(ts)) {
assert(false);
} else if (is_integer(ts)) {
return in;
} else {
assert(false);
}
}
Val* Compiler::number_to_binteger(Val* in, Env* env) {
auto ts = in->type();
if (is_binteger(ts)) {
return in;
} else if (is_float(ts)) {
assert(false);
} else if (is_integer(ts)) {
assert(false);
} else {
assert(false);
}
}
Val* Compiler::number_to_float(Val* in, Env* env) {
auto ts = in->type();
if (is_binteger(ts)) {
assert(false);
} else if (is_float(ts)) {
return in;
} else if (is_integer(ts)) {
assert(false);
} else {
assert(false);
}
}
Val* Compiler::to_math_type(Val* in, MathMode mode, Env* env) {
switch (mode) {
case MATH_BINT:
return number_to_binteger(in, env);
case MATH_INT:
return number_to_integer(in, env);
case MATH_FLOAT:
return number_to_float(in, env);
default:
assert(false);
}
}
Val* Compiler::compile_add(const goos::Object& form, const goos::Object& rest, Env* env) {
auto args = get_va(form, rest);
if (!args.named.empty() || args.unnamed.empty()) {
throw_compile_error(form, "Invalid + form");
}
// look at the first value to determine the math mode
auto first_val = compile_error_guard(args.unnamed.at(0), env);
auto first_type = first_val->type();
auto math_type = get_math_mode(first_type);
switch (math_type) {
case MATH_INT: {
auto result = env->make_gpr(first_type);
env->emit(std::make_unique<IR_RegSet>(result, first_val->to_gpr(env)));
for (size_t i = 1; i < args.unnamed.size(); i++) {
env->emit(std::make_unique<IR_IntegerMath>(
IntegerMathKind::ADD_64, result,
to_math_type(compile_error_guard(args.unnamed.at(i), env), math_type, env)
->to_gpr(env)));
}
return result;
}
case MATH_INVALID:
throw_compile_error(
form, "Cannot determine the math mode for object of type " + first_type.print());
break;
default:
assert(false);
}
assert(false);
return get_none();
}
Val* Compiler::compile_mul(const goos::Object& form, const goos::Object& rest, Env* env) {
auto args = get_va(form, rest);
if (!args.named.empty() || args.unnamed.empty()) {
throw_compile_error(form, "Invalid * form");
}
// look at the first value to determine the math mode
auto first_val = compile_error_guard(args.unnamed.at(0), env);
auto first_type = first_val->type();
auto math_type = get_math_mode(first_type);
switch (math_type) {
case MATH_INT: {
auto result = env->make_gpr(first_type);
env->emit(std::make_unique<IR_RegSet>(result, first_val->to_gpr(env)));
for (size_t i = 1; i < args.unnamed.size(); i++) {
env->emit(std::make_unique<IR_IntegerMath>(
IntegerMathKind::IMUL_32, result,
to_math_type(compile_error_guard(args.unnamed.at(i), env), math_type, env)
->to_gpr(env)));
}
return result;
}
case MATH_INVALID:
throw_compile_error(
form, "Cannot determine the math mode for object of type " + first_type.print());
break;
default:
assert(false);
}
assert(false);
return get_none();
}
Val* Compiler::compile_sub(const goos::Object& form, const goos::Object& rest, Env* env) {
auto args = get_va(form, rest);
if (!args.named.empty() || args.unnamed.empty()) {
throw_compile_error(form, "Invalid - form");
}
auto first_val = compile_error_guard(args.unnamed.at(0), env);
auto first_type = first_val->type();
auto math_type = get_math_mode(first_type);
switch (math_type) {
case MATH_INT:
if (args.unnamed.size() == 1) {
auto result = compile_integer(0, env)->to_gpr(env);
env->emit(std::make_unique<IR_IntegerMath>(
IntegerMathKind::SUB_64, result,
to_math_type(compile_error_guard(args.unnamed.at(0), env), math_type, env)
->to_gpr(env)));
return result;
} else {
auto result = env->make_gpr(first_type);
env->emit(std::make_unique<IR_RegSet>(
result, to_math_type(compile_error_guard(args.unnamed.at(0), env), math_type, env)
->to_gpr(env)));
for (size_t i = 1; i < args.unnamed.size(); i++) {
env->emit(std::make_unique<IR_IntegerMath>(
IntegerMathKind::SUB_64, result,
to_math_type(compile_error_guard(args.unnamed.at(i), env), math_type, env)
->to_gpr(env)));
}
return result;
}
case MATH_INVALID:
throw_compile_error(
form, "Cannot determine the math mode for object of type " + first_type.print());
break;
default:
assert(false);
}
assert(false);
return get_none();
}

View file

@ -1199,6 +1199,26 @@ class IGen {
// TODO, special load/stores of 128 bit values.
// TODO, consider specialized stack loads and stores?
static Instruction load64_gpr64_plus_s32(Register dst_reg, int32_t offset, Register src_reg) {
assert(dst_reg.is_gpr());
assert(src_reg.is_gpr());
Instruction instr(0x8b);
instr.set_modrm_rex_sib_for_reg_reg_disp32(dst_reg.hw_id(), 2, src_reg.hw_id(), true);
instr.set_disp(Imm(4, offset));
return instr;
}
/*!
* Store 64-bits from gpr into memory located at 64-bit reg + 32-bit signed offset.
*/
static Instruction store64_gpr64_plus_s32(Register addr, int32_t offset, Register value) {
assert(addr.is_gpr());
assert(value.is_gpr());
Instruction instr(0x89);
instr.set_modrm_rex_sib_for_reg_reg_disp32(value.hw_id(), 2, addr.hw_id(), true);
instr.set_disp(Imm(4, offset));
return instr;
}
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
// FUNCTION STUFF

View file

@ -485,7 +485,8 @@ bool can_var_be_assigned(int var,
if (lr.has_constraint && lr.assignment.at(instr - lr.min).is_assigned()) {
if (!(ass.occupies_same_reg(lr.assignment.at(instr - lr.min)))) {
if (debug_trace >= 2) {
printf("at idx %d self bad\n", instr);
printf("at idx %d self bad (%s) (%s)\n", instr,
lr.assignment.at(instr - lr.min).to_string().c_str(), ass.to_string().c_str());
}
return false;

View file

@ -21,7 +21,7 @@ struct Assignment {
}
switch (kind) {
case Kind::STACK:
result += fmt::format("stack[{:2d}]", stack_slot);
result += fmt::format("s[{:2d}]", stack_slot);
break;
case Kind::REGISTER:
result += emitter::gRegInfo.get_info(reg).name;

View file

@ -113,6 +113,26 @@ struct CompilerTestRunner {
} // namespace
TEST(CompilerAndRuntime, BuildGame) {
std::thread runtime_thread([]() { exec_runtime(0, nullptr); });
Compiler compiler;
fprintf(stderr, "about to run test\n");
try {
compiler.run_test("goal_src/test/test-build-game.gc");
} catch (std::exception& e) {
fprintf(stderr, "caught exception %s\n", e.what());
EXPECT_TRUE(false);
}
fprintf(stderr, "DONE!\n");
// todo, tests after loading the game.
compiler.shutdown_target();
runtime_thread.join();
}
TEST(CompilerAndRuntime, CompilerTests) {
std::thread runtime_thread([]() { exec_runtime(0, nullptr); });
Compiler compiler;
@ -153,7 +173,18 @@ TEST(CompilerAndRuntime, CompilerTests) {
runner.run_test("test-defun-return-symbol.gc", {"42\n"});
runner.run_test("test-function-return-arg.gc", {"23\n"});
runner.run_test("test-nested-function-call.gc", {"2\n"});
// math
runner.run_test("test-add-int-constants.gc", {"13\n"});
runner.run_test("test-add-int-vars.gc", {"7\n"});
runner.run_test("test-add-int-multiple.gc", {"15\n"});
runner.run_test("test-add-int-multiple-2.gc", {"15\n"});
runner.run_test("test-add-function-returns.gc", {"21\n"});
runner.run_test("test-sub-1.gc", {"4\n"});
runner.run_test("test-sub-2.gc", {"4\n"});
runner.run_test("test-mul-1.gc", {"-12\n"});
compiler.shutdown_target();
runtime_thread.join();
runner.print_summary();
}
}