Skip to content
This repository has been archived by the owner on Jun 26, 2023. It is now read-only.

feat: Add support for typing annotation #90

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 89 additions & 35 deletions .makim.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@ env:
CFLAGS_EXTRA: "\
-fsanitize=address\
"
# use it for ASAN and LSAN
SAN_OPTIONS_DEFAULT: "\
ASAN_OPTIONS_DEFAULT: "\
fast_unwind_on_malloc=0\
:verbosity=1\
:log_threads=1\
:debug=true\
:sleep_before_dying=10\
:print_stats=1\
:strict_string_checks=1\
:detect_stack_use_after_return=1\
:check_initialization_order=1\
:strict_init_order=1\
:atexit=1\
:print_legend=1\
:detect_leaks=1\
"
MESON_EXTRA: "-Db_coverage=true \
-Doptimization=0 \
LSAN_OPTIONS_DEFAULT: "\
fast_unwind_on_malloc=0\
:verbosity=1\
:log_threads=1\
:log_pointers=1\
:strict_string_checks=1\
:detect_leaks=1\
"
MESON_EXTRA_DEBUG: "-Db_coverage=true \
--optimization=0 \
--debug \
-Db_sanitize=address \
"
groups:
Expand Down Expand Up @@ -81,8 +84,8 @@ groups:
- target: clean.gcda
shell: bash
run: |
export ASAN_OPTIONS='{{ args.asan_options or env.SAN_OPTIONS_DEFAULT }}'
export LSAN_OPTIONS='{{ args.lsan_options or env.SAN_OPTIONS_DEFAULT }}'
export ASAN_OPTIONS='{{ args.asan_options or env.ASAN_OPTIONS_DEFAULT }}'
export LSAN_OPTIONS='{{ args.lsan_options or env.LSAN_OPTIONS_DEFAULT }}'

meson setup \
--prefix $CONDA_PREFIX \
Expand All @@ -104,10 +107,10 @@ groups:
- target: build.release
args:
build-type: "debug"
meson-extra: {{ env.MESON_EXTRA }}
meson-extra: {{ env.MESON_EXTRA_DEBUG }}
clean: {{ args.clean }}
asan-options: {{ env.SAN_OPTIONS_DEFAULT }}
lsan-options: {{ env.SAN_OPTIONS_DEFAULT }}
asan-options: {{ env.ASAN_OPTIONS_DEFAULT }}
lsan-options: {{ env.LSAN_OPTIONS_DEFAULT }}

dev:
help: Build for development (+tests +debug)
Expand All @@ -120,10 +123,10 @@ groups:
- target: build.release
args:
build-type: "debug"
meson-extra: {{ env.MESON_EXTRA }} -Ddev=enabled
meson-extra: {{ env.MESON_EXTRA_DEBUG }} -Ddev=enabled
clean: {{ args.clean }}
asan-options: {{ env.SAN_OPTIONS_DEFAULT }}
lsan-options: {{ env.SAN_OPTIONS_DEFAULT }}
asan-options: {{ env.ASAN_OPTIONS_DEFAULT }}
lsan-options: {{ env.LSAN_OPTIONS_DEFAULT }}

env:
targets:
Expand Down Expand Up @@ -198,6 +201,9 @@ groups:

tests:
shell: bash
# env:
# ASAN_OPTIONS: {{ env.ASAN_OPTIONS_DEFAULT }}
# LSAN_OPTIONS: {{ env.LSAN_OPTIONS_DEFAULT }}
targets:
sanitizer:
help: Run sanitizer tests
Expand Down Expand Up @@ -230,8 +236,8 @@ groups:
DEBUG_FLAGS=""

if [[ "{{ args.debug }}" == "True" ]]; then
GDB="gdb --args"
DEBUG_FLAGS="-g"
GDB="gdb core --args"
DEBUG_FLAGS="-g -O0"
fi

TEST_DIR_PATH="./tests"
Expand All @@ -253,16 +259,16 @@ groups:
CLANG_EXTRA="${CLANG_EXTRA} $(pkg-config --cflags --libs arrow-glib)"
CLANG_EXTRA=$(echo "${CLANG_EXTRA}" | sed s/-std=c++14/-std=c++20/g)

env

rm --force "${TMP_DIR}/*.o"

for test_name in {{ args.examples_name }}; do
print_header "${test_name}"
OBJECT_FILE="${TMP_DIR}/${test_name}.o"

echo "Arx build ..."
${ARX} --output "${OBJECT_FILE}" --input "examples/${test_name}.arx"

echo "clang build ..."
set -x
clang++ \
${CLANG_EXTRA} \
Expand Down Expand Up @@ -361,26 +367,74 @@ groups:
run: pre-commit run --all-files --verbose

debug:
env:
OUTPUT_DIR: /tmp/arx
targets:
example:
source-build:
help: Debug arx via an example file
args:
extra:
help: Extra arguments for the build step
type: string
default: ''
test-name:
example-name:
help: Name of the tests that should be executed
type: string
default: ''
required: true
env:
ASAN_OPTIONS: { env.SAN_OPTIONS_DEFAULT }
LSAN_OPTIONS: { env.SAN_OPTIONS_DEFAULT }
debug:
help: Use gdb
type: bool
action: store_true
memory-leak-info:
help: Show ASAN/LSAN information
type: bool
action: store_true
shell: bash
run: |
gdb \
--args build/arx \
--input `pwd`/examples/{{ args.test_name }}.arx \
--output "/tmp/{{ args.test_name }}" {{ args.meson_extra }} \
{% if args.memory_leak_info %}
export ASAN_OPTIONS={{ env.ASAN_OPTIONS_DEFAULT }}
export LSAN_OPTIONS={{ env.LSAN_OPTIONS_DEFAULT }}
{% endif %}

{{ "gdb --args" if args.debug else "" }} build/arx \
--input `pwd`/examples/{{ args.example_name }}.arx \
--output "{{ env.OUTPUT_DIR }}/{{ args.example_name }}.o" \
--build-lib

readelf:
help: Read ELF from an object file
args:
example-name:
help: Name of the tests that should be executed
type: string
required: true
memory-leak-info:
help: Show ASAN/LSAN information
type: bool
action: store_true
dependencies:
- target: debug.source-build
args:
example-name: {{ args.example_name }}
memory-leak-info: {{ args.memory_leak_info }}
run: |
readelf --all "{{ env.OUTPUT_DIR }}/{{ args.example_name }}.o"

objdump:
help: Debug object files using objdump
args:
example-name:
help: Name of the tests that should be executed
type: string
required: true
memory-leak-info:
help: Show ASAN/LSAN information
type: bool
action: store_true
options:
help: Options to be given to objdump
type: string
default: "-d -Mintel"
dependencies:
- target: debug.source-build
args:
example-name: {{ args.example_name }}
memory-leak-info: {{ args.memory_leak_info }}
run: |
objdump {{ args.options }} "{{ env.OUTPUT_DIR }}/{{ args.example_name }}.o"
4 changes: 2 additions & 2 deletions examples/average.arx
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
function average(x y):
(x + y) * 0.5;
fn average(x: float, y: float) -> float:
return (x + y) * 0.5;
4 changes: 2 additions & 2 deletions examples/constant.arx
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
function get_constant(x):
x;
fn get_constant(x: float) -> float:
return x;
8 changes: 4 additions & 4 deletions examples/fibonacci.arx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function fib(x):
if x < 3:
1
fn fib(x: float) -> float:
if x <= 1:
return x;
else:
fib(x-1)+fib(x-2)
return fib(x-1)+fib(x-2);
6 changes: 3 additions & 3 deletions examples/print-star.arx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extern putchard(char);
extern putchard(char) -> void;

function print_star(n):
fn print_star(n: float) -> void:
for i = 1, i < n, 1.0 in
putchard(42); # ascii 42 = '*'
return putchard(42); # ascii 42 = '*'
4 changes: 2 additions & 2 deletions examples/sum.arx
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
function sum(a b):
a + b;
fn sum(a: float, b: float) -> float:
return a + b;
3 changes: 2 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ project('arx', 'cpp', 'c',
license : 'Apache-2.0',
version : '1.6.0', # semantic-release
default_options : [
'warning_level=everything',
#'warning_level=everything',
'warning_level=0',
'cpp_std=c++20',
]
)
Expand Down
66 changes: 60 additions & 6 deletions src/codegen/arx-llvm.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#include <string>

#include <llvm/IR/DIBuilder.h> // for DIBuilder
#include <llvm/IR/IRBuilder.h> // for IRBuilder
#include <llvm/IR/Module.h> // for Module
#include <llvm/Support/Error.h> // for ExitOnError
#include <glog/logging.h> // for COMPACT_GOOGLE_LOG_INFO, LOG
#include <llvm/IR/DIBuilder.h> // for DIBuilder
#include <llvm/IR/IRBuilder.h> // for IRBuilder
#include <llvm/IR/Module.h> // for Module
#include <llvm/Support/Error.h> // for ExitOnError
#include <llvm/Support/TargetSelect.h> // for InitializeAllAsmParsers, Init...
#include <llvm/Target/TargetMachine.h> // for TargetMachine
#include <llvm/Target/TargetOptions.h> // for TargetOptions

#include "codegen/arx-llvm.h" // for ArxLLVM
#include "codegen/jit.h" // for ArxJIT
Expand All @@ -22,6 +27,7 @@ llvm::Type* ArxLLVM::FLOAT_TYPE;
llvm::Type* ArxLLVM::DOUBLE_TYPE;
llvm::Type* ArxLLVM::INT8_TYPE;
llvm::Type* ArxLLVM::INT32_TYPE;
llvm::Type* ArxLLVM::VOID_TYPE;

/* Debug Information Data types */
llvm::DIType* ArxLLVM::DI_FLOAT_TYPE;
Expand All @@ -30,9 +36,9 @@ llvm::DIType* ArxLLVM::DI_INT8_TYPE;
llvm::DIType* ArxLLVM::DI_INT32_TYPE;
llvm::DIType* ArxLLVM::DI_VOID_TYPE;

extern bool IS_BUILD_LIB = false; // default value
llvm::ExitOnError ArxLLVM::exit_on_err;

llvm::Type* ArxLLVM::VOID_TYPE;
extern bool IS_BUILD_LIB = false; // default value

auto ArxLLVM::get_data_type(std::string type_name) -> llvm::Type* {
if (type_name == "float") {
Expand Down Expand Up @@ -71,3 +77,51 @@ auto ArxLLVM::get_di_data_type(std::string di_type_name) -> llvm::DIType* {
llvm::errs() << "[EE] di_type_name not valid.\n";
return nullptr;
}

auto ArxLLVM::initialize() -> void {
// initialize the target registry etc.
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargets();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmParsers();
llvm::InitializeAllAsmPrinters();

// initialize the target registry etc.
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetAsmParser();

ArxLLVM::context = std::make_unique<llvm::LLVMContext>();
ArxLLVM::module =
std::make_unique<llvm::Module>("arx jit", *ArxLLVM::context);

// Create a new builder for the module.
ArxLLVM::ir_builder = std::make_unique<llvm::IRBuilder<>>(*ArxLLVM::context);

// Data Types
ArxLLVM::FLOAT_TYPE = llvm::Type::getFloatTy(*ArxLLVM::context);
ArxLLVM::DOUBLE_TYPE = llvm::Type::getDoubleTy(*ArxLLVM::context);
ArxLLVM::INT8_TYPE = llvm::Type::getInt8Ty(*ArxLLVM::context);
ArxLLVM::INT32_TYPE = llvm::Type::getInt32Ty(*ArxLLVM::context);
ArxLLVM::VOID_TYPE = llvm::Type::getVoidTy(*ArxLLVM::context);

LOG(INFO) << "initialize Target";

// LLVM IR

ArxLLVM::jit = ArxLLVM::exit_on_err(llvm::orc::ArxJIT::Create());
ArxLLVM::module->setDataLayout(ArxLLVM::jit->get_data_layout());

// Create a new builder for the module.
ArxLLVM::di_builder = std::make_unique<llvm::DIBuilder>(*ArxLLVM::module);

// di data types
ArxLLVM::DI_FLOAT_TYPE = ArxLLVM::di_builder->createBasicType(
"float", 32, llvm::dwarf::DW_ATE_float);
ArxLLVM::DI_DOUBLE_TYPE = ArxLLVM::di_builder->createBasicType(
"double", 64, llvm::dwarf::DW_ATE_float);
ArxLLVM::DI_INT8_TYPE = ArxLLVM::di_builder->createBasicType(
"int8", 8, llvm::dwarf::DW_ATE_signed);
ArxLLVM::DI_INT32_TYPE = ArxLLVM::di_builder->createBasicType(
"int32", 32, llvm::dwarf::DW_ATE_signed);
}
3 changes: 3 additions & 0 deletions src/codegen/arx-llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class ArxLLVM {
static std::map<std::string, llvm::AllocaInst*> named_values;
static std::map<std::string, std::unique_ptr<PrototypeAST>> function_protos;

static llvm::ExitOnError exit_on_err;

/* Data types */
static llvm::Type* DOUBLE_TYPE;
static llvm::Type* FLOAT_TYPE;
Expand All @@ -35,6 +37,7 @@ class ArxLLVM {

static auto get_data_type(std::string type_name) -> llvm::Type*;
static auto get_di_data_type(std::string type_name) -> llvm::DIType*;
static auto initialize() -> void;
};

extern bool IS_BUILD_LIB;
Loading