├── eddi_samples ├── hello.eddi ├── constant_print.eddi ├── main.eddi ├── escapes.eddi ├── included.eddi ├── params_assign.eddi ├── problem.eddi ├── asm.eddi ├── ternary.eddi ├── unroll.eddi ├── concat.eddi ├── includes.eddi ├── little_float.eddi ├── errors.eddi ├── empty.eddi ├── warnings.eddi ├── read_cmd.eddi ├── bool_pointers.eddi ├── global_sizes.eddi ├── global_propagation.eddi ├── const.eddi ├── test_structures.eddi ├── type_check.eddi ├── compound.eddi ├── inc.eddi ├── casts.eddi ├── lex.eddi ├── identifiers.eddi ├── functions.eddi ├── grammar.eddi └── memset.eddi ├── AUTHORS ├── test ├── cases │ ├── println.eddi │ ├── global_cp.eddi │ ├── complete_loop_peeling.eddi │ ├── for.eddi │ ├── foreach.eddi │ ├── included.eddi │ ├── includes.eddi │ ├── global_offset_cp.eddi │ ├── args.eddi │ ├── params_assign.eddi │ ├── remove_empty_functions.eddi │ ├── wrong_print.eddi │ ├── string_foreach.eddi │ ├── return_string.eddi │ ├── do_while.eddi │ ├── while.eddi │ ├── remove_empty_loops.eddi │ ├── return_int.eddi │ ├── while_bug.eddi │ ├── common_subexpr_elim.eddi │ ├── globals.eddi │ ├── loop_unrolling.eddi │ ├── complete_loop_peeling_2.eddi │ ├── invalid_inheritance.eddi │ ├── recursive.eddi │ ├── cmov_opt.eddi │ ├── return_pointers.eddi │ ├── stdlib_array_sum.eddi │ ├── void.eddi │ ├── stdlib_math_factorial.eddi │ ├── array_foreach_local.eddi │ ├── array_foreach_global.eddi │ ├── swap.eddi │ ├── loop_unswitching.eddi │ ├── delete_any.eddi │ ├── addressof.eddi │ ├── assign_value.eddi │ ├── stdlib_math_max.eddi │ ├── stdlib_math_min.eddi │ ├── stdlib_math_pow.eddi │ ├── array_foreach_param_local.eddi │ ├── array_foreach_param_global.eddi │ ├── char_members.eddi │ ├── array_foreach_param_param.eddi │ ├── stdlib_string_concat_int.eddi │ ├── char_at.eddi │ ├── struct_member_pointers.eddi │ ├── compound.eddi │ ├── string_pointers.eddi │ ├── float_pointers.eddi │ ├── if.eddi │ ├── stdlib_str_equals.eddi │ ├── bool_pointers.eddi │ ├── pass_member_by_value.eddi │ ├── return_by_value.eddi │ ├── pass_by_value.eddi │ ├── ternary.eddi │ ├── member_function_templates.eddi │ ├── prints.eddi │ ├── invariant_code_motion.eddi │ ├── local_cse.eddi │ ├── int_pointers.eddi │ ├── function_templates.eddi │ ├── stdlib_string_concat.eddi │ ├── struct_arrays.eddi │ ├── cmov.eddi │ ├── parameter_propagation.eddi │ ├── char_type.eddi │ ├── defaults.eddi │ ├── math.eddi │ ├── switch.eddi │ ├── casts.eddi │ ├── member_functions.eddi │ ├── switch_string.eddi │ ├── pointer_arrays.eddi │ ├── int_arrays.eddi │ ├── inc.eddi │ ├── stdlib_string.eddi │ ├── member_functions_param_stack.eddi │ ├── ctor_dtor_stack.eddi │ ├── ctor_dtor_heap.eddi │ ├── member_pointers.eddi │ ├── builtin.eddi │ ├── structures.eddi │ └── copy_constructors.eddi └── UtilsTest.cpp ├── stdlib ├── limits.eddi ├── arrays.eddi ├── timer.eddi └── math.eddi ├── functions ├── x86_32_free.s ├── x86_64_free.s ├── x86_32_time.s ├── x86_32_init.s ├── x86_64_init.s ├── x86_64_time.s ├── x86_32_printS.s ├── x86_64_printS.s ├── x86_32_read_char.s ├── x86_32_printC.s ├── x86_64_printC.s ├── x86_64_read_char.s ├── x86_32_duration.s ├── x86_64_duration.s └── x86_64_printI.s ├── .gitignore ├── .gitmodules ├── tools ├── test_report.sh ├── cases.sh ├── aggregate.awk ├── time_parsing.sh ├── timing.sh └── ci-build.sh ├── src ├── exceptions.cpp ├── ast │ ├── Null.cpp │ ├── True.cpp │ ├── False.cpp │ ├── Boolean.cpp │ ├── Expression.cpp │ ├── ArrayType.cpp │ ├── PointerType.cpp │ ├── SimpleType.cpp │ ├── TemplateType.cpp │ └── BuiltinType.cpp ├── asm │ ├── CodeGenerator.cpp │ ├── IntelAssemblyUtils.cpp │ └── CodeGeneratorFactory.cpp ├── Labels.cpp ├── mtac │ ├── Offset.cpp │ ├── WarningsEngine.cpp │ └── Program.cpp ├── parser_x3 │ └── main.cpp ├── Warnings.cpp ├── BackEnds.cpp ├── FrontEnds.cpp ├── ltac │ ├── FloatRegister.cpp │ └── Operator.cpp ├── AssemblyFileWriter.cpp ├── BackEnd.cpp ├── FrontEnd.cpp ├── PerfsTimer.cpp ├── statistics.cpp ├── SemanticalException.cpp ├── Parameter.cpp └── StopWatch.cpp ├── kernels ├── insertion_sort.eddi ├── bubble_sort.eddi └── bench.sh ├── CONTRIBUTING.md ├── include ├── FrontEnds.hpp ├── NativeBackEnd.hpp ├── ltac │ ├── stack_space.hpp │ ├── pre_alloc_cleanup.hpp │ ├── stack_offsets.hpp │ ├── PeepholeOptimizer.hpp │ ├── register_allocator.hpp │ ├── prologue.hpp │ ├── aggregates.hpp │ ├── forward.hpp │ ├── Printer.hpp │ └── Argument.hpp ├── BaseType.hpp ├── mtac │ ├── Pass.hpp │ ├── reference_resolver.hpp │ ├── BasicBlockExtractor.hpp │ ├── RegisterAllocation.hpp │ ├── WarningsEngine.hpp │ ├── Compiler.hpp │ ├── forward.hpp │ ├── ControlFlowGraph.hpp │ ├── Optimizer.hpp │ ├── EscapeAnalysis.hpp │ ├── local_cse.hpp │ ├── pure_analysis.hpp │ ├── loop_analysis.hpp │ ├── remove_aliases.hpp │ ├── clean_variables.hpp │ ├── parameter_propagation.hpp │ ├── remove_empty_functions.hpp │ ├── ConstantFolding.hpp │ ├── dominators.hpp │ ├── remove_unused_functions.hpp │ ├── BranchOptimizations.hpp │ ├── remove_empty_loops.hpp │ ├── ReduceInStrength.hpp │ ├── loop_invariant_code_motion.hpp │ ├── DeadCodeElimination.hpp │ ├── ArithmeticIdentities.hpp │ ├── induction_variable_optimizations.hpp │ ├── conditional_propagation.hpp │ ├── inlining.hpp │ └── VariableReplace.hpp ├── tac │ └── Size.hpp ├── EDDIFrontEnd.hpp ├── Labels.hpp ├── ast │ ├── Scope.hpp │ ├── Null.hpp │ ├── TypeChecker.hpp │ ├── WarningsEngine.hpp │ ├── StringChecker.hpp │ ├── True.hpp │ ├── False.hpp │ ├── DependenciesResolver.hpp │ ├── source_def.hpp │ ├── Printer.hpp │ ├── structure_check.hpp │ ├── Float.hpp │ ├── Integer.hpp │ ├── function_generation.hpp │ ├── Import.hpp │ ├── TransformerEngine.hpp │ ├── type_finalization.hpp │ ├── CharLiteral.hpp │ ├── values_def.hpp │ ├── Boolean.hpp │ ├── StandardImport.hpp │ ├── Delete.hpp │ ├── Literal.hpp │ ├── PrefixOperation.hpp │ ├── IntegerSuffix.hpp │ ├── DefaultValues.hpp │ ├── Ternary.hpp │ ├── member_function_collection.hpp │ ├── MemberDeclaration.hpp │ ├── NewArray.hpp │ ├── function_collection.hpp │ ├── New.hpp │ ├── FunctionParameter.hpp │ ├── While.hpp │ ├── PointerType.hpp │ ├── Else.hpp │ ├── SimpleType.hpp │ ├── type_collection.hpp │ ├── ElseIf.hpp │ ├── DoWhile.hpp │ ├── VariablesAnnotator.hpp │ ├── Cast.hpp │ ├── VariableValue.hpp │ └── SwitchCase.hpp ├── logging.hpp ├── TerminationException.hpp ├── Target.hpp ├── PerfsTimer.hpp ├── BackEnds.hpp ├── Assembler.hpp ├── documentation.hpp ├── boost_cfg.hpp ├── StopWatch.hpp ├── Platform.hpp ├── statistics.hpp ├── Warnings.hpp ├── timing.hpp └── asm │ └── StringConverter.hpp ├── sonar-project.properties ├── .github └── workflows │ └── make.yml └── LICENSE /eddi_samples/hello.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | print("Hello World"); 3 | } 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Baptiste Wicht 2 | TyRoXx 3 | -------------------------------------------------------------------------------- /test/cases/println.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | println(); 5 | } 6 | -------------------------------------------------------------------------------- /eddi_samples/constant_print.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(123); 5 | } 6 | -------------------------------------------------------------------------------- /test/cases/global_cp.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 55; 5 | int b = a; 6 | } 7 | -------------------------------------------------------------------------------- /stdlib/limits.eddi: -------------------------------------------------------------------------------- 1 | /* 2 | * Standard Library : Limits of integral type 3 | */ 4 | 5 | const MAX_INT = 2147483747 6 | -------------------------------------------------------------------------------- /eddi_samples/main.eddi: -------------------------------------------------------------------------------- 1 | void main(str[] args){ 2 | foreach(str arg in args){ 3 | println(arg); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/cases/complete_loop_peeling.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | for(int i = 0; i < 10; ++i){ 3 | print('i'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /eddi_samples/escapes.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | int a = 6; 3 | test(a); 4 | } 5 | 6 | void test(int* a){ 7 | print(*a); 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/for.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | for(int i = 0; i < 5; ++i){ 5 | print(i); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/cases/foreach.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | foreach(int i from 0 to 5){ 5 | print(i); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/cases/included.eddi: -------------------------------------------------------------------------------- 1 | int sum(int a){ 2 | if(a == 0){ 3 | return 0; 4 | } 5 | 6 | return a + sum(a - 1); 7 | } 8 | -------------------------------------------------------------------------------- /test/cases/includes.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | include "test/cases/included.eddi" 4 | 5 | void main(){ 6 | print(sum(9)); 7 | } 8 | -------------------------------------------------------------------------------- /eddi_samples/included.eddi: -------------------------------------------------------------------------------- 1 | int sum(int a){ 2 | if(a == 0){ 3 | return 0; 4 | } 5 | 6 | return a + sum(a - 1); 7 | } 8 | -------------------------------------------------------------------------------- /test/cases/global_offset_cp.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int b[5]; 5 | b[0] = 55; 6 | 7 | int c = b[0]; 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/args.eddi: -------------------------------------------------------------------------------- 1 | void main(str[] args){ 2 | foreach(str arg in args){ 3 | print(arg); 4 | print("|"); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /eddi_samples/params_assign.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | //Nothing 3 | } 4 | 5 | int sum(int a){ 6 | a = 5; 7 | 8 | return 2; 9 | } 10 | -------------------------------------------------------------------------------- /eddi_samples/problem.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 2 + 99 + 9999 * 222 * 222 + 99 % 90 / 4562; 5 | print(a); 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/params_assign.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | //Nothing 3 | } 4 | 5 | int sum(int a){ 6 | a = 5; 7 | 8 | return 2; 9 | } 10 | -------------------------------------------------------------------------------- /eddi_samples/asm.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 55; 5 | int b = 66; 6 | int c = a + b; 7 | 8 | println(c); 9 | } 10 | -------------------------------------------------------------------------------- /test/cases/remove_empty_functions.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | asdf(9); 5 | } 6 | 7 | void asdf(int a){ 8 | 9 | } 10 | -------------------------------------------------------------------------------- /functions/x86_32_free.s: -------------------------------------------------------------------------------- 1 | _F4freePI: 2 | push ebp 3 | mov ebp, esp 4 | 5 | ;block->available = 1 6 | mov dword [ecx - 8], 1 7 | 8 | leave 9 | ret 10 | -------------------------------------------------------------------------------- /functions/x86_64_free.s: -------------------------------------------------------------------------------- 1 | _F4freePI: 2 | push rbp 3 | mov rbp, rsp 4 | 5 | ;block->available = 1 6 | mov qword [r14 - 16], 1 7 | 8 | leave 9 | ret 10 | -------------------------------------------------------------------------------- /test/cases/wrong_print.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | int array[5]; 3 | 4 | print(array); 5 | } 6 | 7 | void test(int* p){ 8 | print(p); 9 | } 10 | -------------------------------------------------------------------------------- /eddi_samples/ternary.eddi: -------------------------------------------------------------------------------- 1 | int ga = 4; 2 | 3 | void main(){ 4 | int a = ga > 2 ? 44 : 66; 5 | 6 | println(a); 7 | println(ga > 12 ? 44 : 66); 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/string_foreach.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | str a = "asdf"; 3 | 4 | foreach(char c in a){ 5 | print(c); 6 | print("|"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /eddi_samples/unroll.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | int a = 0; 3 | 4 | for(int i = 0; i < 5000; ++i){ 5 | a += i; 6 | } 7 | 8 | print(a); 9 | } 10 | -------------------------------------------------------------------------------- /test/cases/return_string.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(first("abc")); 5 | } 6 | 7 | str first(str a){ 8 | return "abcdef"; 9 | } 10 | -------------------------------------------------------------------------------- /eddi_samples/concat.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | string a("asdf"); 5 | string b("jklé"); 6 | 7 | a.append(b); 8 | 9 | print(a); 10 | } 11 | -------------------------------------------------------------------------------- /eddi_samples/includes.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | include "eddi_samples/included.eddi" 4 | 5 | void main(){ 6 | println(factorial(9)); 7 | println(sum(9)); 8 | } 9 | -------------------------------------------------------------------------------- /eddi_samples/little_float.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | float aaaaa = 4.2; 5 | println(aaaaa); 6 | aaaaa = 3.33; 7 | println(aaaaa); 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/do_while.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int i = 0; 5 | do { 6 | print(i); 7 | ++i; 8 | } while(i < 5); 9 | } 10 | -------------------------------------------------------------------------------- /test/cases/while.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int i = 0; 5 | while(i < 5){ 6 | print(i); 7 | i = i + 1; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /eddi_samples/errors.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | int a = 'a'; 3 | } 4 | 5 | void test(){ 6 | int z = 77.7; 7 | } 8 | 9 | void asdf(){ 10 | int b = "asdf"; 11 | } 12 | -------------------------------------------------------------------------------- /test/cases/remove_empty_loops.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 6; 5 | while(a < 100){ 6 | ++a; 7 | } 8 | print(a); 9 | } 10 | -------------------------------------------------------------------------------- /eddi_samples/empty.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | //This sample does not do anything 3 | //Just here as a test and to verify that as least as possible assembly code is outputted 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/return_int.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(first(22)); 5 | print("|"); 6 | } 7 | 8 | int first(int a){ 9 | return a * a; 10 | } 11 | -------------------------------------------------------------------------------- /eddi_samples/warnings.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a[5]; 5 | a[5]; 6 | 7 | print(a[5]); 8 | } 9 | 10 | void test(){ 11 | print("I'm useless"); 12 | } 13 | -------------------------------------------------------------------------------- /test/cases/while_bug.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int i = 0; 5 | while(i < 5){ 6 | i = ++i; 7 | print("W"); 8 | print(i); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /functions/x86_32_time.s: -------------------------------------------------------------------------------- 1 | _F4timeAI: 2 | push ebp 3 | mov ebp, esp 4 | xor eax, eax 5 | cpuid 6 | rdtsc 7 | mov esi, [ebp + 8] 8 | mov [esi - 4], eax 9 | mov [esi - 8], edx 10 | leave 11 | ret 12 | -------------------------------------------------------------------------------- /test/cases/common_subexpr_elim.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int ga = 99; 4 | 5 | void main(){ 6 | print(ga * 100); 7 | print(ga * 100); 8 | print(ga * 100); 9 | print(ga * 100); 10 | } 11 | -------------------------------------------------------------------------------- /test/cases/globals.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int ga = 1000; 4 | str gb = "a"; 5 | 6 | void main(){ 7 | print(ga); 8 | print(gb); 9 | 10 | ga = ga + 1000; 11 | 12 | print(ga); 13 | } 14 | -------------------------------------------------------------------------------- /test/cases/loop_unrolling.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | int a = 55; 3 | 4 | for(int i = 0; i < 1000; ++i){ 5 | a *= i; 6 | } 7 | 8 | if(a > 0){ 9 | print('i'); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /eddi_samples/read_cmd.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | char c = read_char(); 3 | 4 | if(c == 'e'){ 5 | println("Enter"); 6 | } else { 7 | print("Entered "); 8 | println(c); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/cases/complete_loop_peeling_2.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | for(int i = 0; i < 10; ++i){ 3 | if(i < 5){ 4 | print('a'); 5 | } else { 6 | print('i'); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/cases/invalid_inheritance.eddi: -------------------------------------------------------------------------------- 1 | struct A extends C { 2 | float a; 3 | } 4 | 5 | struct B extends A { 6 | char a; 7 | } 8 | 9 | struct C extends B { 10 | int a; 11 | } 12 | 13 | void main(){ 14 | } 15 | -------------------------------------------------------------------------------- /test/cases/recursive.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(fact(9)); 5 | } 6 | 7 | int fact(int n){ 8 | if(n == 0){ 9 | return 1; 10 | } 11 | 12 | return n * fact(n - 1); 13 | } 14 | -------------------------------------------------------------------------------- /eddi_samples/bool_pointers.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | bool a = false; 5 | test(&a); 6 | } 7 | 8 | void test(bool* a){ 9 | print(*a); 10 | print("|"); 11 | 12 | *a = true; 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | stats 2 | *.v 3 | *.asm 4 | samples/perfs.eddi 5 | *.swp 6 | *.swo 7 | a.out 8 | reports 9 | test_reports 10 | tests.tmp.log 11 | release 12 | debug 13 | release_debug 14 | html 15 | massif.* 16 | *.plist 17 | .cache 18 | -------------------------------------------------------------------------------- /functions/x86_32_init.s: -------------------------------------------------------------------------------- 1 | _F4init: 2 | push ebp 3 | mov ebp, esp 4 | 5 | ; get start of system brk 6 | xor ebx, ebx 7 | mov eax, 45 8 | int 80h 9 | 10 | mov [V_mem_start], eax 11 | mov [V_mem_last], eax 12 | 13 | leave 14 | ret 15 | -------------------------------------------------------------------------------- /functions/x86_64_init.s: -------------------------------------------------------------------------------- 1 | _F4init: 2 | push rbp 3 | mov rbp, rsp 4 | 5 | ; get start of system brk 6 | mov rax, 12 7 | xor rdi, rdi 8 | syscall 9 | 10 | mov [V_mem_start], rax 11 | mov [V_mem_last], rax 12 | 13 | leave 14 | ret 15 | -------------------------------------------------------------------------------- /test/cases/cmov_opt.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int ga = 7; 4 | 5 | void main(){ 6 | int b; 7 | if(ga == 5){ 8 | b = 4; 9 | } else { 10 | b = 8; 11 | } 12 | 13 | print(b); 14 | print("|"); 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/return_pointers.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 55; 5 | int b = 66; 6 | 7 | int* c = second(&a, &b); 8 | print(*c); 9 | } 10 | 11 | int* second(int* a, int* b){ 12 | return b; 13 | } 14 | -------------------------------------------------------------------------------- /test/cases/stdlib_array_sum.eddi: -------------------------------------------------------------------------------- 1 | include 2 | include 3 | 4 | void main(){ 5 | int local[100]; 6 | 7 | for(int i = 0; i < size(local); ++i){ 8 | local[i] = 1; 9 | } 10 | 11 | print(sum(local)); 12 | } 13 | -------------------------------------------------------------------------------- /eddi_samples/global_sizes.eddi: -------------------------------------------------------------------------------- 1 | const int SIZE = 7; 2 | int globalArray[SIZE]; 3 | 4 | void main(){ 5 | println(size(globalArray)); 6 | 7 | const int SIZE2 = 5; 8 | int array[SIZE2]; 9 | 10 | println(size(array)); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /functions/x86_64_time.s: -------------------------------------------------------------------------------- 1 | _F4timeAI: 2 | push rbp 3 | mov rbp, rsp 4 | ;xor rax, rax 5 | ;serialize instruction stream 6 | cpuid 7 | ;rdx:rax = timestamp 8 | rdtsc 9 | mov rsi, [rbp + 16] 10 | mov [rsi - 8], rax 11 | mov [rsi - 16], rdx 12 | leave 13 | ret 14 | -------------------------------------------------------------------------------- /test/cases/void.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | second(22); 5 | } 6 | 7 | void second(int a){ 8 | int b = a + 22; 9 | 10 | print(b); 11 | 12 | third(b); 13 | } 14 | 15 | void third(int c){ 16 | print(c+1); 17 | } 18 | -------------------------------------------------------------------------------- /test/cases/stdlib_math_factorial.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(factorial(0)); 5 | print("|"); 6 | print(factorial(1)); 7 | print("|"); 8 | print(factorial(2)); 9 | print("|"); 10 | print(factorial(9)); 11 | } 12 | -------------------------------------------------------------------------------- /eddi_samples/global_propagation.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int global = 100; 4 | 5 | void main(){ 6 | int a = global; 7 | print(a); 8 | global = 88; 9 | print(global); 10 | a=global; 11 | print(a); 12 | print(global * 1000); 13 | } 14 | -------------------------------------------------------------------------------- /eddi_samples/const.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | const int ga = 22; 4 | const str gb = "22"; 5 | 6 | void main(){ 7 | println(ga); 8 | println(gb); 9 | 10 | const int a = 33; 11 | const str b = "33"; 12 | 13 | println(a); 14 | println(b); 15 | } 16 | -------------------------------------------------------------------------------- /stdlib/arrays.eddi: -------------------------------------------------------------------------------- 1 | /* 2 | * Standard Library : Arrays functions 3 | */ 4 | 5 | //Sum the values of the array 6 | int sum(int[] array){ 7 | int sum = 0; 8 | 9 | foreach(int value in array){ 10 | sum = sum + value; 11 | } 12 | 13 | return sum; 14 | } 15 | -------------------------------------------------------------------------------- /test/cases/array_foreach_local.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int local[5]; 5 | local[0] = 4; 6 | local[1] = 3; 7 | local[2] = 2; 8 | local[3] = 1; 9 | local[4] = 0; 10 | 11 | foreach(int i in local){ 12 | print(i); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/cases/array_foreach_global.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int global[5]; 4 | 5 | void main(){ 6 | global[0] = 4; 7 | global[1] = 3; 8 | global[2] = 2; 9 | global[3] = 1; 10 | global[4] = 0; 11 | 12 | foreach(int i in global){ 13 | print(i); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/swap.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 9; 5 | int b = 11; 6 | a <=> b; 7 | print(a); 8 | print('|'); 9 | print(b); 10 | print('|'); 11 | a <=> b; 12 | print(a); 13 | print('|'); 14 | print(b); 15 | print('|'); 16 | } 17 | -------------------------------------------------------------------------------- /eddi_samples/test_structures.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct Complex { 4 | bool b; 5 | } 6 | 7 | void main(){ 8 | Complex c; 9 | c.b = false; 10 | 11 | test(c); 12 | } 13 | 14 | //Test passing by value 15 | 16 | void test(Complex a){ 17 | print(a.b); 18 | print("|"); 19 | } 20 | -------------------------------------------------------------------------------- /test/cases/loop_unswitching.eddi: -------------------------------------------------------------------------------- 1 | bool b = true; 2 | int limit = 100; 3 | 4 | void main(){ 5 | for(int i = 0; i < limit; ++i){ 6 | if(b){ 7 | print('0'); 8 | print('|'); 9 | } else { 10 | print('1'); 11 | print('|'); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/cases/delete_any.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct Complex { 4 | int* a; 5 | 6 | this(){ 7 | a = new int(); 8 | } 9 | 10 | ~this(){ 11 | delete a; 12 | } 13 | } 14 | 15 | void main(){ 16 | Complex c; 17 | *c.a = 99; 18 | 19 | print(*c.a); 20 | print("|"); 21 | } 22 | -------------------------------------------------------------------------------- /test/cases/addressof.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 44; 5 | 6 | print(a); 7 | print("|"); 8 | 9 | int* b = &a; 10 | 11 | print(*b); 12 | print("|"); 13 | 14 | *b = 55; 15 | 16 | print(*b); 17 | print("|"); 18 | 19 | print(a); 20 | print("|"); 21 | } 22 | -------------------------------------------------------------------------------- /test/cases/assign_value.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 5; 5 | 6 | int b = a = 6; 7 | print(a); 8 | print(b); 9 | b = a = 7; 10 | print(a); 11 | print(b); 12 | a = b = 9; 13 | print(a); 14 | print(b); 15 | a = (b = 1) + 1; 16 | print(a); 17 | print(b); 18 | } 19 | -------------------------------------------------------------------------------- /eddi_samples/type_check.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | sum(1); 3 | sum("asdf"); 4 | 5 | int a[2]; 6 | 7 | sum(a, 2,"asdf",3,9,99, "asdf"); 8 | } 9 | 10 | int sum(int a){ 11 | //Nothing 12 | } 13 | 14 | int sum(str b){ 15 | //Nothing 16 | } 17 | 18 | int sum(int a, int b, str c, str d, int e){ 19 | //Nothing 20 | } 21 | -------------------------------------------------------------------------------- /test/cases/stdlib_math_max.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(max(1000, 999)); 5 | print("|"); 6 | print(max(0, 1)); 7 | print("|"); 8 | print(max(1, 0)); 9 | print("|"); 10 | print(max(-1, 0)); 11 | print("|"); 12 | print(max(0, 0)); 13 | print("|"); 14 | print(max(0, -1)); 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/stdlib_math_min.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(min(1000, 999)); 5 | print("|"); 6 | print(min(0, 1)); 7 | print("|"); 8 | print(min(1, 0)); 9 | print("|"); 10 | print(min(-1, 0)); 11 | print("|"); 12 | print(min(0, 0)); 13 | print("|"); 14 | print(min(0, -1)); 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/stdlib_math_pow.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(pow(0, 10)); 5 | print("|"); 6 | print(pow(10, 0)); 7 | print("|"); 8 | print(pow(10, 1)); 9 | print("|"); 10 | print(pow(10, 2)); 11 | print("|"); 12 | print(pow(2, 10)); 13 | print("|"); 14 | print(pow(1, 100)); 15 | } 16 | -------------------------------------------------------------------------------- /functions/x86_32_printS.s: -------------------------------------------------------------------------------- 1 | _F5printS: 2 | push ebp 3 | mov ebp, esp 4 | 5 | push eax 6 | push ebx 7 | push ecx 8 | push edx 9 | push esi 10 | 11 | mov esi, 0 12 | mov eax, 4 13 | mov ebx, 1 14 | mov ecx, [ebp + 8] 15 | mov edx, [ebp + 12] 16 | int 80h 17 | 18 | pop esi 19 | pop edx 20 | pop ecx 21 | pop ebx 22 | pop eax 23 | 24 | leave 25 | ret 26 | -------------------------------------------------------------------------------- /test/cases/array_foreach_param_local.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int local[5]; 5 | local[0] = 4; 6 | local[1] = 3; 7 | local[2] = 2; 8 | local[3] = 1; 9 | local[4] = 0; 10 | 11 | test(local); 12 | } 13 | 14 | void test(int[] param){ 15 | foreach(int i in param){ 16 | print(i); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /functions/x86_64_printS.s: -------------------------------------------------------------------------------- 1 | _F5printS: 2 | push rbp 3 | mov rbp, rsp 4 | 5 | push rax 6 | push rcx 7 | push rdi 8 | push rsi 9 | push rdx 10 | push r11 11 | 12 | mov rax, 1 13 | mov rdi, 1 14 | mov rsi, [rbp + 16] 15 | mov rdx, [rbp + 24] 16 | syscall 17 | 18 | pop r11 19 | pop rdx 20 | pop rsi 21 | pop rdi 22 | pop rcx 23 | pop rax 24 | 25 | leave 26 | ret 27 | -------------------------------------------------------------------------------- /eddi_samples/compound.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 2; 5 | int b = 3; 6 | 7 | a += 4; 8 | println(a); 9 | 10 | a += b; 11 | println(a); 12 | 13 | a -= b; 14 | println(a); 15 | 16 | a *= b; 17 | println(a); 18 | 19 | a /= b; 20 | println(a); 21 | 22 | a %= b; 23 | println(a); 24 | } 25 | -------------------------------------------------------------------------------- /test/cases/array_foreach_param_global.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int global[5]; 4 | 5 | void main(){ 6 | global[0] = 4; 7 | global[1] = 3; 8 | global[2] = 2; 9 | global[3] = 1; 10 | global[4] = 0; 11 | 12 | test(global); 13 | } 14 | 15 | void test(int[] param){ 16 | foreach(int i in param){ 17 | print(i); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /eddi_samples/inc.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 0; 5 | println(a); 6 | 7 | a++; 8 | println(a); 9 | 10 | ++a; 11 | println(a); 12 | 13 | --a; 14 | println(a); 15 | 16 | a--; 17 | println(a); 18 | 19 | int b = ++a; 20 | println(b); 21 | 22 | b = a++; 23 | 24 | println(b); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /eddi_samples/casts.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 5; 5 | float b = (float) a; 6 | float c = 333.879877; 7 | float d = (float) c; 8 | 9 | println(b); 10 | println((int) b); 11 | println((int) 4.33); 12 | println((int) c); 13 | println((float) a); 14 | 15 | float e = (float) a + 3.33; 16 | println(e); 17 | } 18 | -------------------------------------------------------------------------------- /eddi_samples/lex.eddi: -------------------------------------------------------------------------------- 1 | //Global variables 2 | int a = 1; 3 | str c = "asdf"; 4 | void b(int y, int x){} 5 | void b(int y, int x){ 6 | a <=> b; 7 | c(1, "asdf"); 8 | 9 | while(a < b){ 10 | b <=> a; 11 | } 12 | 13 | for(int a = 0; i < 1; a = 4){ 14 | a = a; 15 | } 16 | 17 | int a = 5 + 4; 18 | } 19 | 20 | void c(str b){ 21 | a <=> c; 22 | } 23 | -------------------------------------------------------------------------------- /functions/x86_32_read_char.s: -------------------------------------------------------------------------------- 1 | _F9read_char: 2 | push ebp 3 | mov ebp, esp 4 | sub esp, 4 5 | 6 | push ebx 7 | push ecx 8 | push edx 9 | push esi 10 | 11 | mov dword [ebp - 4], 0 12 | 13 | mov eax, 3 14 | mov ebx, 0 15 | lea ecx, [ebp - 4] 16 | mov edx, 1 17 | int 80h 18 | 19 | mov eax, [ebp - 4] 20 | 21 | pop esi 22 | pop edx 23 | pop ecx 24 | pop ebx 25 | 26 | add esp, 4 27 | leave 28 | ret 29 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "include/cpp_utils"] 2 | path = include/cpp_utils 3 | url = https://github.com/wichtounet/cpp_utils.git 4 | branch = master 5 | [submodule "make-utils"] 6 | path = make-utils 7 | url = https://github.com/wichtounet/make-utils.git 8 | branch = master 9 | [submodule "cxxopts"] 10 | path = cxxopts 11 | url = https://github.com/jarro2783/cxxopts.git 12 | branch = master 13 | -------------------------------------------------------------------------------- /functions/x86_32_printC.s: -------------------------------------------------------------------------------- 1 | _F5printC: 2 | push ebp 3 | mov ebp, esp 4 | sub esp, 4 5 | 6 | push eax 7 | push ebx 8 | push ecx 9 | push edx 10 | push esi 11 | 12 | mov [ebp - 4], ecx 13 | 14 | mov esi, 0 15 | mov eax, 4 16 | mov ebx, 1 17 | lea ecx, [ebp - 4] 18 | mov edx, 1 19 | int 80h 20 | 21 | pop esi 22 | pop edx 23 | pop ecx 24 | pop ebx 25 | pop eax 26 | 27 | add esp, 4 28 | leave 29 | ret 30 | -------------------------------------------------------------------------------- /functions/x86_64_printC.s: -------------------------------------------------------------------------------- 1 | _F5printC: 2 | push rbp 3 | mov rbp, rsp 4 | sub rsp, 8 5 | 6 | push rax 7 | push rcx 8 | push rdi 9 | push rsi 10 | push rdx 11 | push r11 12 | 13 | mov [rbp - 8], r14 14 | 15 | mov rax, 1 16 | mov rdi, 1 17 | lea rsi, [rbp - 8] 18 | mov rdx, 1 19 | syscall 20 | 21 | pop r11 22 | pop rdx 23 | pop rsi 24 | pop rdi 25 | pop rcx 26 | pop rax 27 | 28 | add rsp, 8 29 | leave 30 | ret 31 | -------------------------------------------------------------------------------- /test/cases/char_members.eddi: -------------------------------------------------------------------------------- 1 | struct chars { 2 | char a; 3 | char b; 4 | char c; 5 | char d; 6 | } 7 | 8 | void main(){ 9 | chars c; 10 | 11 | c.a = 'a'; 12 | c.b = 'b'; 13 | c.c = 'c'; 14 | c.d = 'd'; 15 | 16 | print(c.a); 17 | print('|'); 18 | print(c.b); 19 | print('|'); 20 | print(c.c); 21 | print('|'); 22 | print(c.d); 23 | print('|'); 24 | } 25 | -------------------------------------------------------------------------------- /eddi_samples/identifiers.eddi: -------------------------------------------------------------------------------- 1 | int ga = 1000; 2 | str __3gb = "Global Variable b"; 3 | 4 | int defaultA; 5 | str __defaultB; 6 | 7 | int __3globalArrayA[10]; 8 | str __g3lobalArrayB[10]; 9 | 10 | int __globalUnused = 2222; 11 | 12 | void main(){ 13 | int __asdf999dddd_adsfdafds333 = 0; 14 | } 15 | 16 | void __asdf333(){ 17 | int a = 5; 18 | int _1 = 3; 19 | int __a = 9; 20 | str asdf = ""; 21 | } 22 | -------------------------------------------------------------------------------- /functions/x86_64_read_char.s: -------------------------------------------------------------------------------- 1 | _F9read_char: 2 | push rbp 3 | mov rbp, rsp 4 | sub rsp, 8 5 | 6 | push rcx 7 | push rdi 8 | push rsi 9 | push rdx 10 | push r11 11 | 12 | mov qword [rbp - 8], 0 13 | 14 | mov rax, 0 15 | mov rdi, 0 16 | lea rsi, [rbp - 8] 17 | mov rdx, 1 18 | syscall 19 | 20 | mov rax, [rbp - 8] 21 | 22 | pop r11 23 | pop rdx 24 | pop rsi 25 | pop rdi 26 | pop rcx 27 | 28 | add rsp, 8 29 | leave 30 | ret 31 | -------------------------------------------------------------------------------- /test/cases/array_foreach_param_param.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int local[5]; 5 | local[0] = 4; 6 | local[1] = 3; 7 | local[2] = 2; 8 | local[3] = 1; 9 | local[4] = 0; 10 | 11 | headtest(local); 12 | } 13 | 14 | void headtest(int[] param){ 15 | test(param); 16 | } 17 | 18 | void test(int[] param){ 19 | foreach(int i in param){ 20 | print(i); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/cases/stdlib_string_concat_int.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | string a("test"); 5 | 6 | a.append(987); 7 | 8 | print(a); 9 | print("|"); 10 | 11 | a.append(-561); 12 | 13 | print(a); 14 | print("|"); 15 | 16 | string b("asdf"); 17 | 18 | b.append(98655); 19 | 20 | print(b); 21 | print("|"); 22 | 23 | b.append(1); 24 | 25 | print(b); 26 | print("|"); 27 | } 28 | -------------------------------------------------------------------------------- /eddi_samples/functions.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | println(sum(0)); 5 | println(sum(4)); 6 | println(sum(5)); 7 | 8 | println(my_factorial(9)); 9 | } 10 | 11 | int sum(int a){ 12 | if(a == 0){ 13 | return 0; 14 | } 15 | 16 | return a + sum(a - 1); 17 | } 18 | 19 | int my_factorial(int n){ 20 | if(n == 0){ 21 | return 1; 22 | } 23 | 24 | return n * my_factorial(n - 1); 25 | } 26 | -------------------------------------------------------------------------------- /test/cases/char_at.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | str a = "asdf"; 3 | print(a); 4 | print("|"); 5 | 6 | char b = a[0]; 7 | 8 | print(b); 9 | print("|"); 10 | 11 | b = a[1]; 12 | 13 | print(b); 14 | print("|"); 15 | 16 | print(a[2]); 17 | print("|"); 18 | 19 | if(a[1] == 's'){ 20 | print("1"); 21 | print("|"); 22 | } else { 23 | print("0"); 24 | print("|"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/cases/struct_member_pointers.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct A { 4 | int a; 5 | int* b; 6 | } 7 | 8 | void main(){ 9 | int z = 55; 10 | 11 | A a; 12 | 13 | a.a = 44; 14 | a.b = z; 15 | 16 | print(*a.b); 17 | print("|"); 18 | 19 | a.b = a.a; 20 | 21 | print(*a.b); 22 | print("|"); 23 | 24 | *a.b = 66; 25 | 26 | print(*a.b); 27 | print("|"); 28 | 29 | print(a.a); 30 | print("|"); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /test/cases/compound.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 2; 5 | int b = 3; 6 | 7 | a += 4; 8 | print(a); 9 | print("|"); 10 | 11 | a += b; 12 | print(a); 13 | print("|"); 14 | 15 | a -= b; 16 | print(a); 17 | print("|"); 18 | 19 | a *= b; 20 | print(a); 21 | print("|"); 22 | 23 | a /= b; 24 | print(a); 25 | print("|"); 26 | 27 | a %= b; 28 | print(a); 29 | print("|"); 30 | } 31 | -------------------------------------------------------------------------------- /tools/test_report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | count=0 4 | total=`ls -l test_reports/ | wc -l` 5 | 6 | for file in test_reports/* 7 | do 8 | if grep -q "No errors detected" $file 9 | then 10 | #Nothing to do 11 | echo -n "" 12 | else 13 | count=$count+1 14 | 15 | cat $file 16 | fi 17 | done 18 | 19 | if [[ $count == 0 ]] 20 | then 21 | echo "All tests succeeded" 22 | else 23 | echo "$count/$total failed test cases" 24 | fi 25 | -------------------------------------------------------------------------------- /src/exceptions.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | namespace boost { 11 | 12 | void throw_exception(std::exception const & e){ 13 | throw e; 14 | } 15 | 16 | } // namespace boost 17 | -------------------------------------------------------------------------------- /functions/x86_32_duration.s: -------------------------------------------------------------------------------- 1 | _F8durationAIAI: 2 | push ebp 3 | mov ebp, esp 4 | mov esi, [ebp + 12] 5 | mov edi, [ebp + 8] 6 | mov eax, [esi - 8] 7 | mov ebx, [edi - 8] 8 | sub eax, ebx 9 | cmp eax, 0 10 | jz .second 11 | cmp eax, 0 12 | jge .push_first 13 | neg eax 14 | .push_first: 15 | mov ecx, eax 16 | call _F5printI 17 | .second: 18 | mov eax, [esi - 4] 19 | mov ebx, [edi - 4] 20 | sub eax, ebx 21 | cmp eax, 0 22 | jge .push_second 23 | neg eax 24 | .push_second: 25 | mov ecx, eax 26 | call _F5printI 27 | leave 28 | ret 29 | -------------------------------------------------------------------------------- /test/cases/string_pointers.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | str a = "a"; 3 | test(&a); 4 | 5 | print(a); 6 | print("|"); 7 | } 8 | 9 | void test(str* a){ 10 | print(*a); 11 | print("|"); 12 | 13 | str* b = a; 14 | 15 | print(*b); 16 | print("|"); 17 | 18 | *a = "b"; 19 | 20 | print(*a); 21 | print("|"); 22 | print(*b); 23 | print("|"); 24 | 25 | *b = "c"; 26 | 27 | print(*b); 28 | print("|"); 29 | print(*a); 30 | print("|"); 31 | } 32 | -------------------------------------------------------------------------------- /src/ast/Null.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/Null.hpp" 9 | 10 | using namespace eddic; 11 | 12 | std::ostream& ast::operator<< (std::ostream& stream, ast::Null){ 13 | return stream << "null"; 14 | } 15 | -------------------------------------------------------------------------------- /src/ast/True.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/True.hpp" 9 | 10 | using namespace eddic; 11 | 12 | std::ostream& ast::operator<< (std::ostream& stream, ast::True){ 13 | return stream << "true"; 14 | } 15 | -------------------------------------------------------------------------------- /src/ast/False.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/False.hpp" 9 | 10 | using namespace eddic; 11 | 12 | std::ostream& ast::operator<< (std::ostream& stream, ast::False){ 13 | return stream << "false"; 14 | } 15 | -------------------------------------------------------------------------------- /test/cases/float_pointers.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | float a = 44.4; 5 | test(&a); 6 | 7 | print(a); 8 | print("|"); 9 | } 10 | 11 | void test(float* a){ 12 | print(*a); 13 | print("|"); 14 | 15 | float* b = a; 16 | 17 | print(*b); 18 | print("|"); 19 | 20 | *a = 55.5; 21 | 22 | print(*a); 23 | print("|"); 24 | print(*b); 25 | print("|"); 26 | 27 | *b = 66.6; 28 | 29 | print(*b); 30 | print("|"); 31 | print(*a); 32 | print("|"); 33 | } 34 | -------------------------------------------------------------------------------- /src/ast/Boolean.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/Boolean.hpp" 9 | 10 | using namespace eddic; 11 | 12 | std::ostream& ast::operator<< (std::ostream& stream, const ast::Boolean& b){ 13 | return stream << b.value; 14 | } 15 | -------------------------------------------------------------------------------- /kernels/insertion_sort.eddi: -------------------------------------------------------------------------------- 1 | int array[50000]; 2 | 3 | include 4 | 5 | void main(){ 6 | for(int i = 0; i < size(array); ++i){ 7 | array[i] = size(array) - i; 8 | } 9 | 10 | insertion_sort(); 11 | } 12 | 13 | void insertion_sort(){ 14 | for(int i = 1; i < size(array); ++i){ 15 | int value = array[i]; 16 | int hole = i; 17 | 18 | while(hole > 0 && value < array[hole - 1]){ 19 | array[hole] = array[hole - 1]; 20 | --hole; 21 | } 22 | 23 | array[hole] = value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/cases/if.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | if(5 > 3){ 5 | print(1); 6 | } else { 7 | print(0); 8 | } 9 | 10 | print("|"); 11 | 12 | second(); 13 | 14 | test_bools(); 15 | } 16 | 17 | void second(){ 18 | if(3 > 5){ 19 | print(0); 20 | } else { 21 | print(1); 22 | } 23 | 24 | print("|"); 25 | } 26 | 27 | void test_bools(){ 28 | bool a = 3 > 5; 29 | 30 | if(!a){ 31 | print(1); 32 | } else { 33 | print(0); 34 | } 35 | 36 | print("|"); 37 | } 38 | -------------------------------------------------------------------------------- /test/cases/stdlib_str_equals.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | str a = "asdf"; 5 | str b = "qwer"; 6 | str c = "asd"; 7 | str d = "00"; 8 | str e = "00"; 9 | 10 | print(str_equals(a, a)); 11 | print("|"); 12 | 13 | print(str_equals(a, b)); 14 | print("|"); 15 | 16 | print(str_equals(a, c)); 17 | print("|"); 18 | 19 | print(str_equals(b, c)); 20 | print("|"); 21 | 22 | print(str_equals(a, "asdf")); 23 | print("|"); 24 | 25 | print(str_equals(d, e)); 26 | print("|"); 27 | } 28 | -------------------------------------------------------------------------------- /tools/cases.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | #By default, stay in the current directory and used the installed eddic version 4 | executable=${1:-"eddic"} 5 | base_dir=${2:-"."} 6 | 7 | #Get the directories 8 | cases_dir="$base_dir/test/cases/*.eddi" 9 | 10 | rm -f tmp_ltac_cases 11 | rm -f tmp_mtac_cases 12 | 13 | #Count Statements in test cases 14 | for file in $cases_dir ; do 15 | $executable --ltac-only $file >> tmp_ltac_cases 16 | $executable --mtac-only $file >> tmp_mtac_cases 17 | 18 | echo "" >> tmp_ltac_cases; 19 | echo "" >> tmp_mtac_cases; 20 | done 21 | -------------------------------------------------------------------------------- /src/asm/CodeGenerator.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "asm/CodeGenerator.hpp" 9 | 10 | using namespace eddic; 11 | 12 | as::CodeGenerator::CodeGenerator(AssemblyFileWriter& w, mtac::Program& program) : writer(w), program(program) { 13 | //Nothing to init 14 | } 15 | -------------------------------------------------------------------------------- /test/cases/bool_pointers.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | bool a = false; 5 | test(&a); 6 | 7 | print(a); 8 | print("|"); 9 | } 10 | 11 | void test(bool* a){ 12 | print(*a); 13 | print("|"); 14 | 15 | bool* b = a; 16 | 17 | print(*b); 18 | print("|"); 19 | 20 | *a = true; 21 | 22 | print(*a); 23 | print("|"); 24 | print(*b); 25 | print("|"); 26 | 27 | *b = false; 28 | 29 | print(*b); 30 | print("|"); 31 | print(*a); 32 | print("|"); 33 | 34 | *a = true; 35 | } 36 | -------------------------------------------------------------------------------- /tools/aggregate.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS=":"; 3 | OFS=":"; 4 | } 5 | 6 | /Timers/ { next } 7 | /Total/ { next } 8 | /whole_optimizations/ { next } 9 | /all_optimizations/ { next } 10 | 11 | { 12 | COUNTS[$1] += 1; 13 | TOTALS[$1] += $2; 14 | } 15 | 16 | END { 17 | GLOBAL_TOTAL = 0; 18 | for(ID in COUNTS) { 19 | GLOBAL_TOTAL += TOTALS[ID]; 20 | } 21 | 22 | for(ID in COUNTS) { 23 | if(TOTALS[ID] > 0){ 24 | print TOTALS[ID], ID, (100 * (TOTALS[ID] / GLOBAL_TOTAL)); 25 | } 26 | } 27 | 28 | print "Total", GLOBAL_TOTAL; 29 | } 30 | -------------------------------------------------------------------------------- /src/Labels.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "Labels.hpp" 9 | #include "Utils.hpp" 10 | 11 | __thread int currentLabel = 0; 12 | 13 | std::string eddic::newLabel(){ 14 | return "L" + toString(currentLabel++); 15 | } 16 | 17 | void eddic::resetNumbering(){ 18 | currentLabel = 0; 19 | } 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contribute to eddic 2 | ======================== 3 | 4 | You're welcome to contribute to this project, either if you found a bug or have an idea of improvement. 5 | 6 | If you find issue in the project, post an issue using Github. Or directly fix the error by filling a Pull Request. 7 | 8 | If you think that a feature is lacking, open an issue with the "enhancement" flag. 9 | 10 | Open projects 11 | ------------- 12 | 13 | * Implement a real pass manager for optimizer 14 | * Add a pass to convert the MTAC into SSA form 15 | * Add new data-flow optimization passes 16 | * Add support for Windows 17 | -------------------------------------------------------------------------------- /include/FrontEnds.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef FRONT_ENDS_H 9 | #define FRONT_ENDS_H 10 | 11 | #include 12 | #include 13 | 14 | namespace eddic { 15 | 16 | class FrontEnd; 17 | 18 | std::unique_ptr get_front_end(const std::string& file); 19 | 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tools/time_parsing.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | #By default, stay in the current directory and used the installed eddic version 4 | executable=${1:-"eddic"} 5 | base_dir=${2:-"."} 6 | 7 | #Get the directories 8 | cases_dir="$base_dir/test/cases/*.eddi" 9 | 10 | rm -f eddic_times 11 | 12 | #Time the test case 13 | for file in $cases_dir ; do 14 | echo $file 15 | $executable --O0 --quiet --assembly $file 16 | done 17 | 18 | samples_dir="$base_dir/eddi_samples/*.eddi" 19 | 20 | #Time the samples 21 | for file in $samples_dir ; do 22 | echo $file 23 | $executable --O0 --quiet --assembly $file 24 | done 25 | -------------------------------------------------------------------------------- /test/cases/pass_member_by_value.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct A { 4 | int x; 5 | } 6 | 7 | struct B { 8 | float z; 9 | A a; 10 | } 11 | 12 | struct C { 13 | B b; 14 | A a; 15 | } 16 | 17 | void main(){ 18 | C a; 19 | 20 | a.b.z = 77.77; 21 | a.b.a.x = 66; 22 | a.a.x = 55; 23 | 24 | test(a.b); 25 | test(a.a); 26 | test(a.b.a); 27 | } 28 | 29 | void test(B b){ 30 | print(b.z); 31 | print("|"); 32 | 33 | print(b.a.x); 34 | print("|"); 35 | 36 | test(b.a); 37 | } 38 | 39 | void test(A a){ 40 | print(a.x); 41 | print("|"); 42 | } 43 | -------------------------------------------------------------------------------- /test/cases/return_by_value.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct A { 4 | int a; 5 | int b; 6 | 7 | A new_a(int aa, int bb){ 8 | A x; 9 | x.a = aa; 10 | x.b = bb; 11 | return x; 12 | } 13 | } 14 | 15 | void main(){ 16 | A a = b(99, 66); 17 | 18 | print(a.a); 19 | print("|"); 20 | print(a.b); 21 | print("|"); 22 | 23 | A c = a.new_a(11, 88); 24 | 25 | print(c.a); 26 | print("|"); 27 | print(c.b); 28 | print("|"); 29 | } 30 | 31 | A b(int aa, int bb){ 32 | A a; 33 | a.a = aa; 34 | a.b = bb; 35 | return a; 36 | } 37 | -------------------------------------------------------------------------------- /kernels/bubble_sort.eddi: -------------------------------------------------------------------------------- 1 | int array[50000]; 2 | 3 | void main(){ 4 | for(int i = 0; i < size(array); ++i){ 5 | array[i] = size(array) - i; 6 | } 7 | 8 | bubblesort(); 9 | } 10 | 11 | void bubblesort(){ 12 | bool swapped = false; 13 | 14 | do { 15 | swapped = false; 16 | 17 | for(int i = 1; i < size(array); ++i){ 18 | if(array[i - 1] > array[i]){ 19 | int a = array[i]; 20 | array[i] = array[i - 1]; 21 | array[i - 1] = a; 22 | 23 | swapped = true; 24 | } 25 | } 26 | } while(swapped); 27 | } 28 | -------------------------------------------------------------------------------- /src/ast/Expression.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/Value.hpp" 9 | #include "ast/Expression.hpp" 10 | 11 | using namespace eddic; 12 | 13 | bool ast::has_operation_value(const ast::Operation& op){ 14 | return op.get<0>() != ast::Operator::DEC || op.get<0>() != ast::Operator::INC; 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/pass_by_value.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct A { 4 | int a; 5 | int b; 6 | 7 | this(){ 8 | print("C1"); 9 | print("|"); 10 | } 11 | 12 | this(A* rhs){ 13 | print("C2"); 14 | print("|"); 15 | 16 | a = rhs.a; 17 | b = rhs.b; 18 | } 19 | } 20 | 21 | void main(){ 22 | A a; 23 | a.a = 1; 24 | a.b = 2; 25 | 26 | print(a.a); 27 | print("|"); 28 | print(a.b); 29 | print("|"); 30 | 31 | test(a); 32 | } 33 | 34 | void test(A a){ 35 | print(a.a); 36 | print("|"); 37 | print(a.b); 38 | print("|"); 39 | } 40 | -------------------------------------------------------------------------------- /include/NativeBackEnd.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef NATIVE_BACK_END_H 9 | #define NATIVE_BACK_END_H 10 | 11 | #include "BackEnd.hpp" 12 | 13 | namespace eddic { 14 | 15 | struct NativeBackEnd : public BackEnd { 16 | void generate(mtac::Program& program, Platform platform) override; 17 | }; 18 | 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/ltac/stack_space.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_STACK_SPACE_H 9 | #define LTAC_STACK_SPACE_H 10 | 11 | #include "mtac/forward.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ltac { 16 | 17 | void alloc_stack_space(mtac::Program& program); 18 | 19 | } //end of ltac 20 | 21 | } //end of eddic 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=wichtounet_eddic 2 | sonar.organization=wichtounet-github 3 | 4 | # This is the name and version displayed in the SonarCloud UI. 5 | sonar.projectName=eddic 6 | sonar.projectVersion=1.3.0 7 | 8 | # C++23 support in SonarCloud is experimental, so enable it 9 | sonar.cfamily.cpp23.enabled=true 10 | 11 | # Get coverage from gcov files 12 | #sonar.cfamily.gcov.reportsPath=gcov-reports 13 | 14 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 15 | #sonar.sources=. 16 | 17 | # Encoding of the source code. Default is default system encoding 18 | #sonar.sourceEncoding=UTF-8 19 | -------------------------------------------------------------------------------- /src/mtac/Offset.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "Variable.hpp" 9 | 10 | #include "mtac/Offset.hpp" 11 | 12 | using namespace eddic; 13 | 14 | std::ostream& mtac::operator<<(std::ostream& stream, const Offset& offset){ 15 | return stream << "(" << (offset.variable ? offset.variable->name() : "null") << ")" << offset.offset; 16 | } 17 | -------------------------------------------------------------------------------- /include/BaseType.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef BASE_TYPE_H 9 | #define BASE_TYPE_H 10 | 11 | namespace eddic { 12 | 13 | enum class BaseType : unsigned int { 14 | STRING, 15 | INT, 16 | CHAR, 17 | BOOL, 18 | FLOAT, 19 | VOID 20 | }; 21 | 22 | #define BASETYPE_COUNT 6 23 | 24 | } //end of eddic 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/mtac/Pass.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_PASS_H 9 | #define MTAC_PASS_H 10 | 11 | namespace eddic { 12 | 13 | namespace mtac { 14 | 15 | //Use for two pass optimization 16 | enum class Pass : unsigned int { 17 | DATA_MINING, 18 | OPTIMIZE 19 | }; 20 | 21 | } //end of mtac 22 | 23 | } //end of eddic 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/tac/Size.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TAC_SIZE_H 9 | #define TAC_SIZE_H 10 | 11 | namespace eddic { 12 | 13 | namespace tac { 14 | 15 | enum class Size : char { 16 | DEFAULT, 17 | BYTE, 18 | WORD, 19 | DOUBLE_WORD, 20 | QUAD_WORD 21 | }; 22 | 23 | } //end of tac 24 | 25 | } //end of eddic 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/parser_x3/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "parser_x3/SpiritParser.hpp" 5 | 6 | #include "GlobalContext.hpp" 7 | 8 | using namespace eddic; 9 | 10 | int main(int argc, char** args){ 11 | const std::vector argv(args+1, args+argc); 12 | 13 | for (int i=0; i<100; i++){ 14 | for (auto& file : argv){ 15 | auto context = std::make_shared(Platform::INTEL_X86_64); 16 | parser_x3::SpiritParser parser; 17 | ast::SourceFile source; 18 | 19 | parser.parse(file, source, context); 20 | } 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /eddi_samples/grammar.eddi: -------------------------------------------------------------------------------- 1 | 2 | struct B { 3 | int a; 4 | 5 | int test(){ 6 | 7 | } 8 | } 9 | 10 | struct A { 11 | B a; 12 | 13 | B test(){ 14 | return a; 15 | } 16 | 17 | B test(int b){ 18 | return test(); 19 | } 20 | } 21 | 22 | void test(int a){ 23 | 24 | } 25 | 26 | int clear(){ 27 | return 0; 28 | } 29 | 30 | A* test_ptr(){ 31 | 32 | } 33 | 34 | void main(){ 35 | A a; 36 | 37 | str asdf; 38 | 39 | A array[5]; 40 | 41 | array[a.test(array[0].a.a).a.a + ++a.test(length(asdf) * a.a.a).test()--].a.a = 9; 42 | 43 | test(clear()); 44 | 45 | *test_ptr() = a; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /include/ltac/pre_alloc_cleanup.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_PRE_ALLOC_CLEANUP_H 9 | #define LTAC_PRE_ALLOC_CLEANUP_H 10 | 11 | #include "mtac/forward.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ltac { 16 | 17 | void pre_alloc_cleanup(mtac::Program& program); 18 | 19 | } //end of ltac 20 | 21 | } //end of eddic 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/mtac/reference_resolver.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_REFERENCE_RESOLVER_H 9 | #define MTAC_REFERENCE_RESOLVER_H 10 | 11 | #include "mtac/forward.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace mtac { 16 | 17 | void resolve_references(mtac::Program& program); 18 | 19 | } //end of mtac 20 | 21 | } //end of eddic 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /test/cases/ternary.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 5 > 2 ? 44 : 66; 5 | print(a); 6 | print("|"); 7 | 8 | print(5 > 12 ? 44 : 66); 9 | print("|"); 10 | 11 | str b = 5 > 2 ? "44" : "66"; 12 | print(b); 13 | print("|"); 14 | 15 | print(5 > 12 ? "44" : "66"); 16 | print("|"); 17 | 18 | bool c = 5 > 2 ? true : false; 19 | print(c); 20 | print("|"); 21 | 22 | print(5 > 12 ? true : false); 23 | print("|"); 24 | 25 | float d = 5 > 2 ? 44.4 : 66.6; 26 | print(d); 27 | print("|"); 28 | 29 | print(5 > 12 ? 44.4 : 66.6); 30 | print("|"); 31 | } 32 | -------------------------------------------------------------------------------- /include/EDDIFrontEnd.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef EDDI_FRONT_END_H 9 | #define EDDI_FRONT_END_H 10 | 11 | #include "FrontEnd.hpp" 12 | 13 | namespace eddic { 14 | 15 | struct EDDIFrontEnd : public FrontEnd { 16 | std::unique_ptr compile(const std::string& file, Platform platform, GlobalContext & context); 17 | }; 18 | 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /test/cases/member_function_templates.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct A { 4 | int a; 5 | 6 | template 7 | void test(POD value){ 8 | this.a = this.a + 1; 9 | 10 | print(this.a); 11 | print("|"); 12 | print(value); 13 | print("|"); 14 | } 15 | 16 | template 17 | void deep_test(POD first, PODD second){ 18 | this.test(first); 19 | this.test(second); 20 | } 21 | } 22 | 23 | void main(){ 24 | A value; 25 | value.test(5); 26 | value.test("5"); 27 | value.deep_test(5.5, "5"); 28 | value.deep_test(100, true); 29 | } 30 | -------------------------------------------------------------------------------- /test/cases/prints.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | print(111); 5 | print("|"); 6 | print(0); 7 | print("|"); 8 | print(-111); 9 | print("|"); 10 | 11 | print(false); 12 | print("|"); 13 | print(true); 14 | print("|"); 15 | 16 | print(999.99); 17 | print("|"); 18 | print(1.009); 19 | print("|"); 20 | print(0.0); 21 | print("|"); 22 | print(-1.009); 23 | print("|"); 24 | print(-999.990); 25 | print("|"); 26 | 27 | print(""); 28 | print("|"); 29 | print("-0"); 30 | print("|"); 31 | print("asdf"); 32 | print("|"); 33 | print("1234asdf"); 34 | print("|"); 35 | } 36 | -------------------------------------------------------------------------------- /test/cases/invariant_code_motion.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int ga = 9; 4 | 5 | void main(){ 6 | int b = 0; 7 | for(int i = 0; i < 100; ++i){ 8 | int c = ga * 55; 9 | b += c; 10 | } 11 | 12 | int c = 9; 13 | for(int i = 0; i < 25; ++i){ 14 | if(i == 0){ 15 | int d = ga * 88; 16 | c += d; 17 | } else { 18 | c += 9; 19 | } 20 | } 21 | 22 | int d = 10; 23 | for(int i = 0; i < 100; ++i){ 24 | for(int j = 0; j < 100; ++j){ 25 | int e = ga * 99; 26 | d += e; 27 | } 28 | } 29 | 30 | print(b); 31 | print(c); 32 | print(d); 33 | } 34 | -------------------------------------------------------------------------------- /test/cases/local_cse.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int ga = 9; 4 | int gb = 99; 5 | int gc = 999; 6 | 7 | void main(){ 8 | test_a(); 9 | test_b(); 10 | } 11 | 12 | void test_a(){ 13 | int a = ga * 99; 14 | int b = 99 * ga; 15 | int c = ga * 99; 16 | int d = 99 * 99; 17 | 18 | print(a); 19 | print("|"); 20 | print(b); 21 | print("|"); 22 | print(c); 23 | print("|"); 24 | print(d); 25 | print("|"); 26 | } 27 | 28 | void test_b(){ 29 | int a = gb * gc; 30 | int b = gc * gb; 31 | int c = gb * gc; 32 | 33 | print(a); 34 | print("|"); 35 | print(b); 36 | print("|"); 37 | print(c); 38 | print("|"); 39 | } 40 | -------------------------------------------------------------------------------- /include/Labels.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LABELS_H 9 | #define LABELS_H 10 | 11 | #include "Utils.hpp" 12 | 13 | namespace eddic { 14 | 15 | std::string newLabel(); 16 | void resetNumbering(); 17 | 18 | template 19 | std::string label(const std::string& prefix, T value){ 20 | return prefix + toString(value); 21 | } 22 | 23 | } //end of eddic 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/Warnings.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | #include "Warnings.hpp" 11 | 12 | void eddic::warn(const std::string& warning){ 13 | std::cout << "warning: " << warning << std::endl; 14 | } 15 | 16 | void eddic::warn(const std::string& position, const std::string& warning){ 17 | std::cout << position << std::endl << "warning: " << warning << std::endl; 18 | } 19 | -------------------------------------------------------------------------------- /test/cases/int_pointers.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 44; 5 | test(&a); 6 | 7 | print(a); 8 | print("|"); 9 | } 10 | 11 | void test(int* a){ 12 | print(*a); 13 | print("|"); 14 | 15 | int* b = a; 16 | 17 | print(*b); 18 | print("|"); 19 | 20 | *a = 55; 21 | 22 | print(*a); 23 | print("|"); 24 | print(*b); 25 | print("|"); 26 | 27 | *b = 66; 28 | 29 | print(*b); 30 | print("|"); 31 | print(*a); 32 | print("|"); 33 | } 34 | 35 | //Just here to test the parsing of null 36 | //This function has no effect 37 | void testparser(int* a){ 38 | int* b = a; 39 | b = null; 40 | } 41 | -------------------------------------------------------------------------------- /include/ltac/stack_offsets.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_STACK_OFFSETS_H 9 | #define LTAC_STACK_OFFSETS_H 10 | 11 | #include "Platform.hpp" 12 | 13 | #include "mtac/forward.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace ltac { 18 | 19 | void fix_stack_offsets(mtac::Program& program, Platform platform); 20 | 21 | } //end of ltac 22 | 23 | } //end of eddic 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/ltac/PeepholeOptimizer.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_PEEPHOLE_OPTIMIZER_H 9 | #define LTAC_PEEPHOLE_OPTIMIZER_H 10 | 11 | #include "Platform.hpp" 12 | 13 | #include "mtac/forward.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace ltac { 18 | 19 | void optimize(mtac::Program& program, Platform platform); 20 | 21 | } //end of ltac 22 | 23 | } //end of eddic 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /eddi_samples/memset.eddi: -------------------------------------------------------------------------------- 1 | struct A { 2 | int a; 3 | int b; 4 | int c; 5 | int d; 6 | } 7 | 8 | struct B { 9 | int b; 10 | int c; 11 | int d; 12 | } 13 | 14 | struct Small { 15 | int a; 16 | int b; 17 | } 18 | 19 | struct D { 20 | int z; 21 | } 22 | 23 | void main(){ 24 | A a1; 25 | B b1; 26 | B b2; 27 | B b3; 28 | B b4; 29 | A a2; 30 | B b5; 31 | A a3; 32 | A a4; 33 | A a5; 34 | 35 | test_small(); 36 | test_middle(); 37 | } 38 | 39 | void test_small(){ 40 | Small small; 41 | } 42 | 43 | void test_middle(){ 44 | Small s1; 45 | Small s2; 46 | Small s3; 47 | Small s4; 48 | Small s5; 49 | D d; 50 | } 51 | -------------------------------------------------------------------------------- /src/ast/ArrayType.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/ArrayType.hpp" 9 | 10 | using namespace eddic; 11 | 12 | bool ast::operator==(const ast::ArrayType& a, const ast::ArrayType& b){ 13 | return a.type.get() == b.type.get(); 14 | } 15 | 16 | std::ostream& ast::operator<<(std::ostream& out, const ast::ArrayType& type){ 17 | return out << "Array Type " << type.type; 18 | } 19 | -------------------------------------------------------------------------------- /include/mtac/BasicBlockExtractor.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_BASIC_BLOCK_EXTRACTOR_H 9 | #define MTAC_BASIC_BLOCK_EXTRACTOR_H 10 | 11 | #include 12 | 13 | #include "mtac/forward.hpp" 14 | 15 | namespace eddic::mtac { 16 | 17 | void extract_basic_blocks(mtac::Program & program); 18 | void clear_basic_blocks(mtac::Program & program); 19 | 20 | } // namespace eddic::mtac 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /test/cases/function_templates.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | test(9); 5 | test(5.5); 6 | 7 | test(9,99); 8 | test(9.9,100); 9 | test("a","b"); 10 | 11 | deep_test(9, 5.5, "a"); 12 | } 13 | 14 | template 15 | void test(T i){ 16 | print(i); 17 | print("|"); 18 | } 19 | 20 | template 21 | void test(T a, S b){ 22 | print(a); 23 | print("|"); 24 | print(b); 25 | print("|"); 26 | } 27 | 28 | template 29 | void deep_test(S s, T t, U u){ 30 | test(s); 31 | test(t); 32 | test(u); 33 | test(s,s); 34 | test(u,u); 35 | } 36 | -------------------------------------------------------------------------------- /include/ast/Scope.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_SCOPE_H 9 | #define AST_SCOPE_H 10 | 11 | #include 12 | #include 13 | 14 | namespace eddic { 15 | 16 | namespace ast { 17 | 18 | /*! 19 | * \class If 20 | * \brief The AST node for a if. 21 | */ 22 | struct Scope { 23 | std::vector instructions; 24 | }; 25 | 26 | } //end of ast 27 | 28 | } //end of eddic 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/logging.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LOGGING_H 9 | #define LOGGING_H 10 | 11 | #ifdef LOGGING_DISABLE 12 | 13 | #define LOG if(false) log::emit 14 | 15 | #else 16 | 17 | #define LOG log::emit 18 | 19 | #endif 20 | 21 | #include "logging/logging.h" 22 | 23 | using namespace ::logging; 24 | 25 | namespace eddic { 26 | 27 | void configure_logging(int level); 28 | 29 | } //end of eddic 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/mtac/RegisterAllocation.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_REGISTER_ALLOCATION_H 9 | #define MTAC_REGISTER_ALLOCATION_H 10 | 11 | #include "Platform.hpp" 12 | 13 | #include "mtac/forward.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace mtac { 18 | 19 | void register_param_allocation(mtac::Program& program, Platform platform); 20 | 21 | } //end of mtac 22 | 23 | } //end of eddic 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/ast/Null.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_NULL_H 9 | #define AST_NULL_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class Null 19 | * \brief Represent a null pointer. 20 | */ 21 | struct Null { 22 | 23 | }; 24 | 25 | std::ostream& operator<< (std::ostream& stream, Null); 26 | 27 | } //end of ast 28 | 29 | } //end of eddic 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/ast/TypeChecker.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TYPE_CHECKER_H 9 | #define TYPE_CHECKER_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct TypeCheckingPass : Pass { 18 | void apply_program(ast::SourceFile& program, bool indicator) override; 19 | bool is_simple() override; 20 | }; 21 | 22 | } //end of ast 23 | 24 | } //end of eddic 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/BackEnds.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "BackEnds.hpp" 9 | #include "BackEnd.hpp" 10 | #include "NativeBackEnd.hpp" 11 | 12 | using namespace eddic; 13 | 14 | std::unique_ptr eddic::get_back_end(Output output){ 15 | switch(output){ 16 | case Output::NATIVE_EXECUTABLE: 17 | return std::make_unique(); 18 | default: 19 | return nullptr; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/ast/PointerType.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/PointerType.hpp" 9 | 10 | using namespace eddic; 11 | 12 | bool ast::operator==(const ast::PointerType& a, const ast::PointerType& b){ 13 | return a.type.get() == b.type.get(); 14 | } 15 | 16 | std::ostream& ast::operator<<(std::ostream& out, const ast::PointerType& type){ 17 | return out << "Pointer Type " << type.type.get(); 18 | } 19 | -------------------------------------------------------------------------------- /src/ast/SimpleType.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/SimpleType.hpp" 9 | 10 | using namespace eddic; 11 | 12 | bool ast::operator==(const ast::SimpleType& a, const ast::SimpleType& b){ 13 | return a.const_ == b.const_ && a.type == b.type; 14 | } 15 | 16 | std::ostream& ast::operator<<(std::ostream& out, const ast::SimpleType& type){ 17 | return out << "Simple Type " << type.type; 18 | } 19 | -------------------------------------------------------------------------------- /test/cases/stdlib_string_concat.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | string a("asdf"); 5 | string b("1234"); 6 | string c("you"); 7 | 8 | print(a); 9 | print("|"); 10 | print(b); 11 | print("|"); 12 | print(c); 13 | print("|"); 14 | 15 | a.append(b); 16 | 17 | print(a); 18 | print("|"); 19 | print(b); 20 | print("|"); 21 | print(c); 22 | print("|"); 23 | 24 | b.append(a); 25 | 26 | print(a); 27 | print("|"); 28 | print(b); 29 | print("|"); 30 | print(c); 31 | print("|"); 32 | 33 | c.append(b); 34 | 35 | print(a); 36 | print("|"); 37 | print(b); 38 | print("|"); 39 | print(c); 40 | print("|"); 41 | } 42 | -------------------------------------------------------------------------------- /include/ast/WarningsEngine.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef WARNINGS_ENGINE_H 9 | #define WARNINGS_ENGINE_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct WarningsPass : Pass { 18 | void apply_program(ast::SourceFile& program, bool indicator) override; 19 | bool is_simple() override; 20 | }; 21 | 22 | } //end of ast 23 | 24 | } //end of eddic 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/ast/StringChecker.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef STRING_CHECKER_H 9 | #define STRING_CHECKER_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct StringCollectionPass : Pass { 18 | void apply_program(ast::SourceFile& program, bool indicator) override; 19 | bool is_simple() override; 20 | }; 21 | 22 | } //end of ast 23 | 24 | } //end of eddic 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/ltac/register_allocator.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_REGISTER_ALLOCATOR_H 9 | #define LTAC_REGISTER_ALLOCATOR_H 10 | 11 | #include 12 | 13 | #include "Platform.hpp" 14 | 15 | #include "mtac/forward.hpp" 16 | 17 | namespace eddic { 18 | 19 | namespace ltac { 20 | 21 | void register_allocation(mtac::Program& program, Platform platform); 22 | 23 | } //end of mtac 24 | 25 | } //end of eddic 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /test/cases/struct_arrays.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct Complex { 4 | int imag; 5 | int real; 6 | } 7 | 8 | void main(){ 9 | Complex a[2]; 10 | 11 | a[0].imag = 99; 12 | a[0].real = 111; 13 | 14 | a[1].imag = 999; 15 | a[1].real = 1111; 16 | 17 | print(a[0].imag); 18 | print("|"); 19 | print(a[0].real); 20 | print("|"); 21 | 22 | print(a[1].imag); 23 | print("|"); 24 | print(a[1].real); 25 | print("|"); 26 | 27 | test(a); 28 | } 29 | 30 | void test(Complex[] a){ 31 | print(a[0].imag); 32 | print("|"); 33 | print(a[0].real); 34 | print("|"); 35 | 36 | print(a[1].imag); 37 | print("|"); 38 | print(a[1].real); 39 | print("|"); 40 | } 41 | -------------------------------------------------------------------------------- /include/ast/True.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_TRUE_H 9 | #define AST_TRUE_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class True 19 | * \brief Reprensent a true boolean literal. 20 | */ 21 | struct True { 22 | 23 | }; 24 | 25 | std::ostream& operator<< (std::ostream& stream, True true_); 26 | 27 | } //end of ast 28 | 29 | } //end of eddic 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/ltac/prologue.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_PROLOGUE_H 9 | #define LTAC_PROLOGUE_H 10 | 11 | #include 12 | 13 | #include "Options.hpp" 14 | 15 | #include "mtac/forward.hpp" 16 | 17 | namespace eddic { 18 | 19 | namespace ltac { 20 | 21 | void generate_prologue_epilogue(mtac::Program& program, std::shared_ptr configuration); 22 | 23 | } //end of ltac 24 | 25 | } //end of eddic 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /test/cases/cmov.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int ga = 7; 4 | int gb = 77; 5 | int gc = 99; 6 | 7 | void main(){ 8 | int b; 9 | if(ga == 5){ 10 | b = 4; 11 | } else { 12 | b = 8; 13 | } 14 | 15 | print(b); 16 | print("|"); 17 | 18 | int c; 19 | if(ga > 5){ 20 | c = 4; 21 | } else { 22 | c = 8; 23 | } 24 | 25 | print(c); 26 | print("|"); 27 | 28 | int d; 29 | if(ga < 5){ 30 | d = gb; 31 | } else { 32 | d = gc; 33 | } 34 | 35 | print(d); 36 | print("|"); 37 | 38 | int e; 39 | if(ga > 5){ 40 | e = gb; 41 | } else { 42 | e = gc; 43 | } 44 | 45 | print(e); 46 | print("|"); 47 | } 48 | -------------------------------------------------------------------------------- /test/cases/parameter_propagation.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct A { 4 | int a; 5 | } 6 | 7 | int ga = 9; 8 | 9 | void main(){ 10 | A a; 11 | 12 | test_a(a, 6); 13 | test_b(a, 8); 14 | test_b(a, 10); 15 | test_c(a, 5, 6); 16 | test_d(a, 99, ga, 99); 17 | } 18 | 19 | void test_a(A a, int b){ 20 | print(b); 21 | print("|"); 22 | } 23 | 24 | void test_b(A a, int b){ 25 | print(b); 26 | print("|"); 27 | } 28 | 29 | void test_c(A a, int b, int c){ 30 | print(b); 31 | print("|"); 32 | print(c); 33 | print("|"); 34 | } 35 | 36 | void test_d(A a, int b, int c, int d){ 37 | print(b); 38 | print("|"); 39 | print(c); 40 | print("|"); 41 | print(d); 42 | print("|"); 43 | } 44 | -------------------------------------------------------------------------------- /include/ast/False.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_FALSE_H 9 | #define AST_FALSE_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class False 19 | * \brief Reprensent a false boolean literal. 20 | */ 21 | struct False { 22 | 23 | }; 24 | 25 | std::ostream& operator<< (std::ostream& stream, False false_); 26 | 27 | } //end of ast 28 | 29 | } //end of eddic 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/mtac/WarningsEngine.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_WARNINGS_ENGINE_H 9 | #define MTAC_WARNINGS_ENGINE_H 10 | 11 | #include 12 | 13 | #include "mtac/forward.hpp" 14 | 15 | namespace eddic { 16 | 17 | struct Configuration; 18 | 19 | namespace mtac { 20 | 21 | void collect_warnings(mtac::Program& program, std::shared_ptr configuration); 22 | 23 | } //end of mtac 24 | 25 | } //end of eddic 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /test/cases/char_type.eddi: -------------------------------------------------------------------------------- 1 | void main(){ 2 | char a = 'a'; 3 | print(a); 4 | print("|"); 5 | 6 | pass('x'); 7 | 8 | print('0'); 9 | print("|"); 10 | 11 | if(a == 'a'){ 12 | print('z'); 13 | print("|"); 14 | } else { 15 | print('y'); 16 | print("|"); 17 | } 18 | 19 | print(test('a', 'a')); 20 | print("|"); 21 | print(test('z', 'z')); 22 | print("|"); 23 | print(test('a', 'z')); 24 | print("|"); 25 | print(test('z', 'a')); 26 | print("|"); 27 | } 28 | 29 | void pass(char a){ 30 | print(a); 31 | print('|'); 32 | } 33 | 34 | char test(char a, char b){ 35 | if(a == b){ 36 | return 'e'; 37 | } else { 38 | return 'u'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /include/ast/DependenciesResolver.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef DEPENDENCIES_RESOLVER_H 9 | #define DEPENDENCIES_RESOLVER_H 10 | 11 | #include "ast/source_def.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace parser_x3 { 16 | struct SpiritParser; 17 | } 18 | 19 | namespace ast { 20 | 21 | void resolveDependencies(ast::SourceFile& program, parser_x3::SpiritParser& parser); 22 | 23 | } //end of ast 24 | 25 | } //end of eddic 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /functions/x86_64_duration.s: -------------------------------------------------------------------------------- 1 | _F8durationAIAI: 2 | push rbp 3 | mov rbp, rsp 4 | ;start timestamp 5 | mov rsi, [rbp + 24] 6 | ;end timestamp 7 | mov rdi, [rbp + 16] 8 | ;print the high order bytes 9 | mov rax, [rsi - 16] 10 | mov rbx, [rdi - 16] 11 | sub rax, rbx 12 | ;if the first diff is 0, do not print 0 13 | cmp rax, 0 14 | jz .second 15 | ;if it's negative, we print the positive only 16 | cmp rax, 0 17 | jge .push_first 18 | neg rax 19 | .push_first: 20 | mov r14, rax 21 | call _F5printI 22 | ;print the low order bytes 23 | .second: 24 | mov rax, [rsi - 8] 25 | mov rbx, [rdi - 8] 26 | sub rax, rbx 27 | ;If it's negative, we print the positive only 28 | cmp rax, 0 29 | jge .push_second 30 | neg rax 31 | .push_second: 32 | mov r14, rax 33 | call _F5printI 34 | leave 35 | ret 36 | -------------------------------------------------------------------------------- /test/UtilsTest.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | #include "Utils.hpp" 11 | 12 | #define BOOST_TEST_DYN_LINK 13 | #include 14 | 15 | BOOST_AUTO_TEST_CASE( toString ){ 16 | std::string result = eddic::toString(33); 17 | 18 | BOOST_CHECK_EQUAL (result, "33"); 19 | } 20 | 21 | BOOST_AUTO_TEST_CASE( toNumber ){ 22 | int value = eddic::toNumber("22"); 23 | 24 | BOOST_CHECK_EQUAL (value, 22); 25 | } 26 | -------------------------------------------------------------------------------- /tools/timing.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | #By default, stay in the current directory and used the installed eddic version 4 | executable=${1:-"eddic"} 5 | base_dir=${2:-"."} 6 | 7 | #Get the directories 8 | cases_dir="$base_dir/test/cases/*.eddi" 9 | 10 | rm -f eddic_times 11 | 12 | #Time the test case 13 | for file in $cases_dir ; do 14 | echo $file 15 | $executable --64 --O3 --quiet --time $file >> eddic_times 16 | done 17 | 18 | samples_dir="$base_dir/eddi_samples/*.eddi" 19 | 20 | #Time the samples 21 | for file in $samples_dir ; do 22 | echo $file 23 | $executable --64 --O3 --quiet --time $file >> eddic_times 24 | done 25 | 26 | #Display results 27 | awk 'BEGIN { FS = " " } ; { print $1 }' eddic_times | sed "s/ms//g" | awk -f tools/aggregate.awk | sort -nr 28 | -------------------------------------------------------------------------------- /stdlib/timer.eddi: -------------------------------------------------------------------------------- 1 | /* 2 | * Standard Library : Interface to time some code. 3 | */ 4 | 5 | struct Timer { 6 | int start1; 7 | int start2; 8 | int end1; 9 | int end2; 10 | } 11 | 12 | void start_timer(Timer* timer){ 13 | int start[2]; 14 | time(start); 15 | 16 | timer.start1 = start[0]; 17 | timer.start2 = start[1]; 18 | } 19 | 20 | void end_timer(Timer* timer){ 21 | int end[2]; 22 | time(end); 23 | 24 | timer.end1 = end[0]; 25 | timer.end2 = end[1]; 26 | } 27 | 28 | void print_timer(Timer* timer){ 29 | int start[2]; 30 | int end[2]; 31 | 32 | start[0] = timer.start1; 33 | start[1] = timer.start2; 34 | 35 | end[0] = timer.end1; 36 | end[1] = timer.end2; 37 | 38 | duration(start, end); 39 | } 40 | -------------------------------------------------------------------------------- /include/TerminationException.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TERMINATION_EXCEPTION_H 9 | #define TERMINATION_EXCEPTION_H 10 | 11 | namespace eddic { 12 | 13 | /*! 14 | * \struct TerminationException 15 | * \brief An exception indicating that an other exception has been found and already handled and that 16 | * the compilation has to be terminated. 17 | */ 18 | class TerminationException: public std::exception { 19 | //Nothing 20 | }; 21 | 22 | } //end of eddic 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/mtac/Compiler.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_COMPILER_H 9 | #define MTAC_COMPILER_H 10 | 11 | #include "ast/source_def.hpp" 12 | 13 | #include "mtac/forward.hpp" 14 | 15 | namespace eddic { 16 | 17 | struct StringPool; 18 | 19 | namespace mtac { 20 | 21 | struct Compiler { 22 | void compile(ast::SourceFile& source, const std::shared_ptr& pool, mtac::Program& program) const; 23 | }; 24 | 25 | } //end of mtac 26 | 27 | } //end of eddic 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/ast/source_def.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_SOURCE_FILE_DEF_H 9 | #define AST_SOURCE_FILE_DEF_H 10 | 11 | namespace eddic { 12 | 13 | namespace ast { 14 | 15 | struct SourceFile; 16 | struct struct_definition; 17 | 18 | //Functions 19 | 20 | struct Constructor; 21 | struct Destructor; 22 | struct TemplateFunctionDeclaration; 23 | 24 | //Instructions 25 | 26 | struct FunctionCall; 27 | struct Expression; 28 | 29 | } //end of ast 30 | 31 | } //end of eddic 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/ltac/aggregates.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_AGGREGATES_H 9 | #define LTAC_AGGREGATES_H 10 | 11 | #include "mtac/forward.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ltac { 16 | 17 | /*! 18 | * \brief Allocate aggregates variables into their own stack positions for the 19 | * LTAC compiler. 20 | * \param program The MTAC Program 21 | */ 22 | void allocate_aggregates(mtac::Program& program); 23 | 24 | } //end of ltac 25 | 26 | } //end of eddic 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/ast/TemplateType.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ast/TemplateType.hpp" 9 | 10 | #include "Utils.hpp" 11 | 12 | using namespace eddic; 13 | 14 | bool ast::operator==(const ast::TemplateType& a, const ast::TemplateType& b){ 15 | return a.type == b.type && are_equals(a.template_types, b.template_types); 16 | } 17 | 18 | std::ostream& ast::operator<<(std::ostream& out, const ast::TemplateType& type){ 19 | return out << "Template Type " << type.type; 20 | } 21 | -------------------------------------------------------------------------------- /test/cases/defaults.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a; 5 | print(a); 6 | print("|"); 7 | 8 | bool b; 9 | print(b); 10 | print("|"); 11 | 12 | float c; 13 | print(c); 14 | print("|"); 15 | 16 | str d; 17 | print(d); 18 | print("|"); 19 | 20 | int array1[2]; 21 | print(array1[0]); 22 | print("|"); 23 | print(array1[1]); 24 | print("|"); 25 | 26 | bool array2[2]; 27 | print(array2[0]); 28 | print("|"); 29 | print(array2[1]); 30 | print("|"); 31 | 32 | float array3[2]; 33 | print(array3[0]); 34 | print("|"); 35 | print(array3[1]); 36 | print("|"); 37 | 38 | str array4[2]; 39 | print(array4[0]); 40 | print("|"); 41 | print(array4[1]); 42 | print("|"); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/FrontEnds.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "FrontEnd.hpp" 9 | #include "FrontEnds.hpp" 10 | #include "EDDIFrontEnd.hpp" 11 | #include "Utils.hpp" 12 | 13 | using namespace eddic; 14 | 15 | std::unique_ptr eddic::get_front_end(const std::string& file){ 16 | //Handle .eddi files with the EDDI FrontEnd 17 | if(has_extension(file, "eddi")){ 18 | return std::make_unique(); 19 | } 20 | 21 | //This kind of file is not handled 22 | return nullptr; 23 | } 24 | -------------------------------------------------------------------------------- /include/mtac/forward.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_FORWARD_DECLARATIONS_H 9 | #define MTAC_FORWARD_DECLARATIONS_H 10 | 11 | #include 12 | 13 | #include "variant.hpp" 14 | 15 | namespace eddic::mtac { 16 | 17 | struct Program; 18 | class Function; 19 | 20 | class basic_block; 21 | using basic_block_p = std::shared_ptr; 22 | using basic_block_cp = std::shared_ptr; 23 | 24 | struct Quadruple; 25 | 26 | } // namespace eddic::mtac 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/Target.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TARGET_MACROS_H 9 | #define TARGET_MACROS_H 10 | 11 | namespace eddic { 12 | 13 | #ifdef __GNUG__ 14 | #ifdef __LP64__ 15 | static const bool Target64 = true; 16 | #else 17 | static const bool Target64 = false; 18 | #endif 19 | static const bool TargetDetermined = true; 20 | #else 21 | static const bool Target64 = false; 22 | static const bool TargetDetermined = false; 23 | #endif 24 | 25 | } //end of eddic 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/ast/Printer.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_PRINTER_H 9 | #define AST_PRINTER_H 10 | 11 | #include "ast/source_def.hpp" 12 | #include "ast/Value.hpp" 13 | #include "ast/Instruction.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace ast { 18 | 19 | struct Printer { 20 | void print(SourceFile& program); 21 | void print(Value& value); 22 | void print(Instruction& value); 23 | void print(Expression& value); 24 | }; 25 | 26 | } //end of ast 27 | 28 | } //end of eddic 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/ltac/FloatRegister.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ltac/FloatRegister.hpp" 9 | 10 | using namespace eddic; 11 | 12 | ltac::FloatRegister::FloatRegister(){ 13 | //Nothing to init 14 | } 15 | 16 | ltac::FloatRegister::FloatRegister(unsigned short reg) : reg(reg) { 17 | //Nothing to init 18 | } 19 | 20 | ltac::FloatRegister::operator int(){ 21 | return reg; 22 | } 23 | 24 | std::ostream& ltac::operator<<(std::ostream& out, const ltac::FloatRegister& reg){ 25 | return out << "fr" << reg.reg; 26 | } 27 | -------------------------------------------------------------------------------- /test/cases/math.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | //Variables are global to avoid optimizations 4 | int ga = 111; 5 | int gb = 222; 6 | int gc = -111; 7 | int gd = -222; 8 | int ge = 1000; 9 | 10 | void main(){ 11 | print(ga + gb); 12 | print("|"); 13 | print(gb - ga); 14 | print("|"); 15 | print(ga - gb); 16 | print("|"); 17 | print(0 * ga); 18 | print("|"); 19 | print(gc * gd); 20 | print("|"); 21 | print(gb / ga); 22 | print("|"); 23 | print(gd / ga); 24 | print("|"); 25 | print(gd / gb); 26 | print("|"); 27 | print(gd / gd); 28 | print("|"); 29 | print(gd / gc); 30 | print("|"); 31 | print(gd % gc); 32 | print("|"); 33 | print(gc % gd); 34 | print("|"); 35 | print(ge % 256); 36 | print("|"); 37 | print(ge % 64); 38 | print("|"); 39 | } 40 | -------------------------------------------------------------------------------- /.github/workflows/make.yml: -------------------------------------------------------------------------------- 1 | name: Linux Build 2 | 3 | on: 4 | push: 5 | branches: [ "develop" ] 6 | pull_request: 7 | branches: [ "develop" ] 8 | 9 | jobs: 10 | build: 11 | name: Compile and test on Linux 12 | runs-on: ubuntu-latest 13 | container: 14 | image: wichtounet/cpp:latest 15 | strategy: 16 | matrix: 17 | compiler: [gcc, clang] 18 | 19 | steps: 20 | - name: Checkout code 21 | uses: actions/checkout@v3 22 | with: 23 | submodules: recursive 24 | - name: Build binaries 25 | run: make -j5 release_debug_bin compiler=${{ matrix.compiler }} 26 | 27 | - name: Build tests 28 | run: make -j5 release_debug_test compiler=${{ matrix.compiler }} 29 | 30 | - name: Run tests 31 | run: make run_release_debug_test compiler=${{ matrix.compiler }} 32 | -------------------------------------------------------------------------------- /include/ast/structure_check.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_STRUCTURE_CHECK_PASS_H 9 | #define AST_STRUCTURE_CHECK_PASS_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct StructureCheckPass : Pass { 18 | void apply_struct(ast::struct_definition& struct_, bool indicator) override; 19 | 20 | GlobalContext & context; 21 | StructureCheckPass(GlobalContext & context) : context(context) {} 22 | }; 23 | 24 | } //end of ast 25 | 26 | } //end of eddic 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/mtac/ControlFlowGraph.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_CONTROL_FLOW_GRAPH_H 9 | #define MTAC_CONTROL_FLOW_GRAPH_H 10 | 11 | #include 12 | 13 | #include "mtac/forward.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace mtac { 18 | 19 | void make_edge(mtac::basic_block_p from, mtac::basic_block_p to); 20 | void remove_edge(mtac::basic_block_p from, mtac::basic_block_p to); 21 | 22 | void build_control_flow_graph(mtac::Function& function); 23 | 24 | } //end of mtac 25 | 26 | } //end of eddic 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/ast/Float.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_FLOAT_H 9 | #define AST_FLOAT_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class Float 19 | * \brief The AST node for a float. 20 | */ 21 | struct Float { 22 | double value; 23 | }; 24 | 25 | } //end of ast 26 | 27 | } //end of eddic 28 | 29 | //Adapt the struct for the AST 30 | BOOST_FUSION_ADAPT_STRUCT( 31 | eddic::ast::Float, 32 | (double, value) 33 | ) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /test/cases/switch.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 5; 5 | 6 | switch(a){ 7 | case 3: 8 | print("3"); 9 | case 4: 10 | print("4"); 11 | case 5: 12 | print("5"); 13 | case 6: 14 | print("6"); 15 | default: 16 | print("default"); 17 | } 18 | 19 | print("|"); 20 | 21 | test(a); 22 | test(3); 23 | test(6); 24 | test(100); 25 | test(4); 26 | } 27 | 28 | void test(int a){ 29 | switch(a){ 30 | case 3: 31 | print("3"); 32 | case 4: 33 | print("4"); 34 | case 5: 35 | print("5"); 36 | case 6: 37 | print("6"); 38 | default: 39 | print("default"); 40 | } 41 | 42 | print("|"); 43 | } 44 | -------------------------------------------------------------------------------- /include/PerfsTimer.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef PERFS_TIMER_H 9 | #define PERFS_TIMER_H 10 | 11 | #include 12 | 13 | #include "StopWatch.hpp" 14 | 15 | namespace eddic { 16 | 17 | class PerfsTimer { 18 | public: 19 | PerfsTimer(const std::string& n); 20 | PerfsTimer(const std::string& n, bool precise); 21 | 22 | ~PerfsTimer(); 23 | 24 | private: 25 | StopWatch timer; 26 | std::string name; 27 | bool precise = false; 28 | }; 29 | 30 | } //end of eddic 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/AssemblyFileWriter.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "AssemblyFileWriter.hpp" 9 | 10 | #include "SemanticalException.hpp" 11 | 12 | using namespace eddic; 13 | 14 | AssemblyFileWriter::AssemblyFileWriter(const std::string& path) { 15 | m_stream.open(path.c_str()); 16 | 17 | if (!m_stream) { 18 | throw SemanticalException("Unable to open the output file"); 19 | } 20 | } 21 | 22 | AssemblyFileWriter::~AssemblyFileWriter() { 23 | } 24 | 25 | std::ostream& AssemblyFileWriter::stream() { 26 | return m_stream; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /include/ast/Integer.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_INTEGER_H 9 | #define AST_INTEGER_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class Integer 19 | * \brief The AST node for an integer. 20 | */ 21 | struct Integer { 22 | int value; 23 | }; 24 | 25 | } //end of ast 26 | 27 | } //end of eddic 28 | 29 | //Adapt the struct for the AST 30 | BOOST_FUSION_ADAPT_STRUCT( 31 | eddic::ast::Integer, 32 | (int, value) 33 | ) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/ast/function_generation.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_FUNCTION_GENERATION_PASS_H 9 | #define AST_FUNCTION_GENERATION_PASS_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct FunctionGenerationPass : Pass { 18 | void apply_struct(ast::struct_definition& struct_, bool indicator) override; 19 | 20 | GlobalContext & context; 21 | FunctionGenerationPass(GlobalContext & context) : context(context) {} 22 | }; 23 | 24 | } //end of ast 25 | 26 | } //end of eddic 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/BackEnd.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "BackEnd.hpp" 9 | 10 | using namespace eddic; 11 | 12 | void BackEnd::set_string_pool(std::shared_ptr pool){ 13 | this->pool = pool; 14 | } 15 | 16 | std::shared_ptr BackEnd::get_string_pool(){ 17 | return pool; 18 | } 19 | 20 | void BackEnd::set_configuration(std::shared_ptr configuration){ 21 | this->configuration = configuration; 22 | } 23 | 24 | std::shared_ptr BackEnd::get_configuration(){ 25 | return configuration; 26 | } 27 | -------------------------------------------------------------------------------- /kernels/bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TIMEFORMAT='%3R' 4 | 5 | ITERATIONS=2 6 | 7 | function bench_base(){ 8 | min=0.0 9 | 10 | /tmp/ramdrive/dev/eddic/bin/eddic --quiet --O$1 $2 11 | 12 | for i in `seq 1 $ITERATIONS` 13 | do 14 | { time ./a.out ; } 2> tmp 15 | 16 | result=`cat tmp` 17 | 18 | if [[ $result < $min ]] 19 | then 20 | min=$result 21 | fi 22 | 23 | if [[ $min == 0.0 ]] 24 | then 25 | min=$result 26 | fi 27 | done 28 | 29 | printf "%s O%d min:%0.3f \n" $2 $1 $min 30 | 31 | rm a.out 32 | rm tmp 33 | } 34 | 35 | function bench(){ 36 | file=kernels/$1.eddi 37 | 38 | bench_base 0 $file 39 | bench_base 1 $file 40 | bench_base 2 $file 41 | bench_base 3 $file 42 | } 43 | 44 | bench bubble_sort 45 | bench insertion_sort 46 | -------------------------------------------------------------------------------- /src/FrontEnd.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "FrontEnd.hpp" 9 | 10 | using namespace eddic; 11 | 12 | void FrontEnd::set_string_pool(std::shared_ptr pool){ 13 | this->pool = pool; 14 | } 15 | 16 | std::shared_ptr FrontEnd::get_string_pool(){ 17 | return pool; 18 | } 19 | 20 | void FrontEnd::set_configuration(std::shared_ptr configuration){ 21 | this->configuration = configuration; 22 | } 23 | 24 | std::shared_ptr FrontEnd::get_configuration(){ 25 | return configuration; 26 | } 27 | -------------------------------------------------------------------------------- /include/mtac/Optimizer.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_OPTIMIZER_H 9 | #define MTAC_OPTIMIZER_H 10 | 11 | #include 12 | 13 | #include "Platform.hpp" 14 | #include "Options.hpp" 15 | 16 | #include "mtac/forward.hpp" 17 | 18 | namespace eddic { 19 | 20 | struct StringPool; 21 | 22 | namespace mtac { 23 | 24 | struct Optimizer { 25 | void optimize(mtac::Program& program, std::shared_ptr pool, Platform platform, std::shared_ptr configuration) const ; 26 | }; 27 | 28 | } //end of mtac 29 | 30 | } //end of eddic 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /test/cases/casts.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | int a = 5; 5 | float b = (float) a; 6 | float c = 333.879877; 7 | float d = (float) c; 8 | 9 | print(b); 10 | print("|"); 11 | print((int) b); 12 | print("|"); 13 | print((int) 4.33); 14 | print("|"); 15 | print((int) c); 16 | print("|"); 17 | print((float) a); 18 | print("|"); 19 | 20 | float e = (float) a + 3.33; 21 | print(e); 22 | print("|"); 23 | 24 | test_char_casts(); 25 | } 26 | 27 | void debug(int c){ 28 | print(c); 29 | print("|"); 30 | } 31 | 32 | void debug(char c){ 33 | print(c); 34 | print("|"); 35 | } 36 | 37 | void test_char_casts(){ 38 | int a = 66; 39 | 40 | char c = (char) a; 41 | char d = (char) c; 42 | 43 | debug(c); 44 | debug(d); 45 | 46 | int e = (int) 'Z'; 47 | debug(e); 48 | } 49 | -------------------------------------------------------------------------------- /include/ast/Import.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_IMPORT_H 9 | #define AST_IMPORT_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class Import 19 | * \brief The AST node for an import. 20 | */ 21 | struct Import : x3::file_position_tagged { 22 | std::string file; 23 | }; 24 | 25 | } //end of ast 26 | 27 | } //end of eddic 28 | 29 | //Adapt the struct for the AST 30 | BOOST_FUSION_ADAPT_STRUCT( 31 | eddic::ast::Import, 32 | (std::string, file) 33 | ) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/ast/BuiltinType.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the Boost Software License: Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "cpp_utils/assert.hpp" 9 | 10 | #include "ast/Value.hpp" 11 | #include "ast/BuiltinOperator.hpp" 12 | 13 | using namespace eddic; 14 | 15 | std::ostream& ast::operator<< (std::ostream& stream, ast::BuiltinType type){ 16 | switch(type){ 17 | case ast::BuiltinType::SIZE: 18 | return stream << "SIZE"; 19 | case ast::BuiltinType::LENGTH: 20 | return stream << "LENGTH"; 21 | default: 22 | cpp_unreachable("Unhandled builtin type"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/cases/member_functions.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct Counter { 4 | int value; 5 | 6 | void increment(){ 7 | value = value + 1; 8 | } 9 | 10 | void add(int number){ 11 | value = value + number; 12 | } 13 | 14 | void add(int n1, int n2){ 15 | value = value + n1; 16 | value = value + n2; 17 | } 18 | 19 | void addSub(int n1, int n2){ 20 | add(n1); 21 | add(n2); 22 | } 23 | } 24 | 25 | void main(){ 26 | Counter counter; 27 | print(counter.value); 28 | print("|"); 29 | counter.increment(); 30 | print(counter.value); 31 | print("|"); 32 | counter.add(99); 33 | print(counter.value); 34 | print("|"); 35 | counter.add(11, 69); 36 | print(counter.value); 37 | print("|"); 38 | counter.addSub(11, 69); 39 | print(counter.value); 40 | print("|"); 41 | } 42 | -------------------------------------------------------------------------------- /include/ast/TransformerEngine.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TRANSFORMER_ENGINE_H 9 | #define TRANSFORMER_ENGINE_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct CleanPass : Pass { 18 | void apply_program(ast::SourceFile& program, bool indicator) override; 19 | bool is_simple() override; 20 | }; 21 | 22 | struct TransformPass : Pass { 23 | void apply_program(ast::SourceFile& program, bool indicator) override; 24 | bool is_simple() override; 25 | }; 26 | 27 | } //end of ast 28 | 29 | } //end of eddic 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /test/cases/switch_string.eddi: -------------------------------------------------------------------------------- 1 | include 2 | include 3 | 4 | void main(){ 5 | str a = "5"; 6 | 7 | switch(a){ 8 | case "3": 9 | print("3"); 10 | case "4": 11 | print("4"); 12 | case "5": 13 | print("5"); 14 | case "6": 15 | print("6"); 16 | default: 17 | print("default"); 18 | } 19 | 20 | print("|"); 21 | 22 | test(a); 23 | test("3"); 24 | test("6"); 25 | test("100"); 26 | test("4"); 27 | } 28 | 29 | void test(str a){ 30 | switch(a){ 31 | case "3": 32 | print("3"); 33 | case "4": 34 | print("4"); 35 | case "5": 36 | print("5"); 37 | case "6": 38 | print("6"); 39 | default: 40 | print("default"); 41 | } 42 | 43 | print("|"); 44 | } 45 | -------------------------------------------------------------------------------- /include/ast/type_finalization.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2024. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_TYPE_FINALIZATION_PASS_H 9 | #define AST_TYPE_FINALIZATION_PASS_H 10 | 11 | #include 12 | #include 13 | 14 | #include "ast/Pass.hpp" 15 | #include "Type.hpp" 16 | 17 | namespace eddic::ast { 18 | 19 | struct TypeFinalizationPass : Pass { 20 | void apply_struct(ast::struct_definition & struct_, bool indicator) override; 21 | 22 | GlobalContext & context; 23 | TypeFinalizationPass(GlobalContext & context) : context(context) {} 24 | }; 25 | 26 | } // namespace eddic::ast 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/ast/CharLiteral.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_CHAR_LITERAL_H 9 | #define AST_CHAR_LITERAL_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace eddic { 16 | 17 | namespace ast { 18 | 19 | /*! 20 | * \class CharLiteral 21 | * \brief The AST node for a char literal. 22 | */ 23 | struct CharLiteral { 24 | char value; 25 | }; 26 | 27 | } //end of ast 28 | 29 | } //end of eddic 30 | 31 | //Adapt the struct for the AST 32 | BOOST_FUSION_ADAPT_STRUCT( 33 | eddic::ast::CharLiteral, 34 | (char, value) 35 | ) 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/ast/values_def.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef VALUES_DEF_H 9 | #define VALUES_DEF_H 10 | 11 | namespace eddic { 12 | 13 | namespace ast { 14 | 15 | struct Integer; 16 | struct IntegerSuffix; 17 | struct Float; 18 | struct Literal; 19 | struct True; 20 | struct False; 21 | struct Boolean; 22 | struct Null; 23 | struct Cast; 24 | struct New; 25 | struct BuiltinOperator; 26 | struct NewArray; 27 | struct PrefixOperation; 28 | struct Ternary; 29 | struct VariableValue; 30 | struct Assignment; 31 | struct FunctionCall; 32 | struct Expression; 33 | 34 | } //end of ast 35 | 36 | } //end of eddic 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/ast/Boolean.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_BOOLEAN_H 9 | #define AST_BOOLEAN_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace eddic { 16 | 17 | namespace ast { 18 | 19 | /*! 20 | * \class Boolean 21 | * \brief Reprensent a boolean literal. 22 | */ 23 | struct Boolean { 24 | bool value; 25 | }; 26 | 27 | std::ostream& operator<< (std::ostream& stream, const Boolean& bool_); 28 | 29 | } //end of ast 30 | 31 | } //end of eddic 32 | 33 | BOOST_FUSION_ADAPT_STRUCT( 34 | eddic::ast::Boolean, 35 | (bool, value) 36 | ) 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/mtac/EscapeAnalysis.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_ESCAPE_ANALYSIS_H 9 | #define MTAC_ESCAPE_ANALYSIS_H 10 | 11 | #include 12 | #include 13 | 14 | #include "mtac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | class Variable; 19 | 20 | namespace mtac { 21 | 22 | typedef std::unordered_set> escaped_variables; 23 | typedef std::unique_ptr>> escaped_variables_ptr; 24 | 25 | escaped_variables_ptr escape_analysis(mtac::Function& function); 26 | 27 | } //end of eddic 28 | 29 | } //end of mtac 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /test/cases/pointer_arrays.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int* globalArray[2]; 4 | 5 | void main(){ 6 | int a = 55; 7 | int b = 66; 8 | 9 | globalArray[0] = a; 10 | globalArray[1] = b; 11 | 12 | print(*globalArray[0]); 13 | print("|"); 14 | print(*globalArray[1]); 15 | print("|"); 16 | 17 | *globalArray[0] = 555; 18 | *globalArray[1] = 666; 19 | 20 | print(*globalArray[0]); 21 | print("|"); 22 | print(*globalArray[1]); 23 | print("|"); 24 | 25 | second(); 26 | } 27 | 28 | void second(){ 29 | int* array[2]; 30 | 31 | int a = 55; 32 | int b = 66; 33 | 34 | array[0] = a; 35 | array[1] = b; 36 | 37 | print(*array[0]); 38 | print("|"); 39 | print(*array[1]); 40 | print("|"); 41 | 42 | *array[0] = 555; 43 | *array[1] = 666; 44 | 45 | print(*array[0]); 46 | print("|"); 47 | print(*array[1]); 48 | print("|"); 49 | } 50 | -------------------------------------------------------------------------------- /src/PerfsTimer.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "PerfsTimer.hpp" 9 | #include "logging.hpp" 10 | 11 | using namespace eddic; 12 | 13 | PerfsTimer::PerfsTimer(const std::string& n) : name(n) {} 14 | PerfsTimer::PerfsTimer(const std::string& n, bool precise) : name(n), precise(precise) {} 15 | 16 | PerfsTimer::~PerfsTimer(){ 17 | if(log::enabled()){ 18 | if(precise){ 19 | LOG("Perfs") << name << " took " << timer.micro_elapsed() << "us" << log::endl; 20 | } else { 21 | LOG("Perfs") << name << " took " << timer.elapsed() << "ms" << log::endl; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /functions/x86_64_printI.s: -------------------------------------------------------------------------------- 1 | _F5printI: 2 | push rbp 3 | mov rbp, rsp 4 | 5 | push rax 6 | push rbx 7 | push rcx 8 | push rdx 9 | push rsi 10 | push rdi 11 | push r11 12 | 13 | ;The parameter is in r14 14 | mov rax, r14 15 | xor r14, r14 16 | ;If the number is negative, we print the - and then the number 17 | or rax, rax 18 | jge .loop 19 | neg rax 20 | ;Print "-" 21 | push 1 22 | push S2 23 | call _F5printS 24 | add rsp, 16 25 | ;Divide rax until there is nothing to divide 26 | .loop: 27 | xor rdx, rdx 28 | mov rbx, 10 29 | div rbx 30 | add rdx, 48 31 | push rdx 32 | inc r14 33 | or rax, rax 34 | jz .next 35 | jmp .loop 36 | ;Print each of the char, one by one 37 | .next: 38 | or r14, r14 39 | jz .exit 40 | dec r14 41 | mov rax, 1 42 | mov rdi, 1 43 | mov rsi, rsp 44 | mov rdx, 1 45 | syscall 46 | add rsp, 8 47 | jmp .next 48 | .exit: 49 | 50 | pop r11 51 | pop rdi 52 | pop rsi 53 | pop rdx 54 | pop rcx 55 | pop rbx 56 | pop rax 57 | 58 | leave 59 | ret 60 | -------------------------------------------------------------------------------- /include/ast/StandardImport.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_STANDARD_IMPORT_H 9 | #define AST_STANDARD_IMPORT_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class StandardImport 19 | * \brief The AST node for an import of the standard import. 20 | */ 21 | struct StandardImport : x3::file_position_tagged { 22 | std::string header; 23 | }; 24 | 25 | } //end of ast 26 | 27 | } //end of eddic 28 | 29 | //Adapt the struct for the AST 30 | BOOST_FUSION_ADAPT_STRUCT( 31 | eddic::ast::StandardImport, 32 | (std::string, header) 33 | ) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/mtac/WarningsEngine.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "Warnings.hpp" 9 | #include "Options.hpp" 10 | 11 | #include "mtac/WarningsEngine.hpp" 12 | #include "mtac/Program.hpp" 13 | 14 | using namespace eddic; 15 | 16 | void mtac::collect_warnings(mtac::Program& program, std::shared_ptr configuration){ 17 | if(configuration->option_defined("warning-unused")){ 18 | for(auto& function : program.functions){ 19 | if(program.cg.node(function.definition())->in_edges.size() == 0 && !function.is_main()){ 20 | warn("Unused function: " + function.get_name()); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /include/ast/Delete.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_DELETE_H 9 | #define AST_DELETE_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class Delete 19 | * \brief The AST node for delete a variable. 20 | */ 21 | struct Delete : x3::file_position_tagged { 22 | Value value; 23 | x3::unused_type fake_; 24 | 25 | }; 26 | 27 | } //end of ast 28 | 29 | } //end of eddic 30 | 31 | //Adapt the struct for the AST 32 | BOOST_FUSION_ADAPT_STRUCT( 33 | eddic::ast::Delete, 34 | (eddic::ast::Value, value) 35 | (x3::unused_type, fake_) 36 | ) 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/BackEnds.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef BACK_ENDS_H 9 | #define BACK_ENDS_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | class BackEnd; 16 | 17 | /*! 18 | * \enum Output 19 | * \brief Output type of the Compiler. 20 | * This output type allows to determine which backend has to be used. 21 | */ 22 | enum class Output : unsigned int { 23 | NATIVE_EXECUTABLE 24 | }; 25 | 26 | /*! 27 | * Return the appropriate back end for the given Output type. 28 | * \param output The output type. 29 | * \return The appropriate back end. 30 | */ 31 | std::unique_ptr get_back_end(Output output); 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /test/cases/int_arrays.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int globalArray[7]; 4 | 5 | void main(){ 6 | globalArray[0] = 5; 7 | int array[7]; 8 | 9 | array[0] = 1; 10 | array[1] = array[0]; 11 | print(array[1]); 12 | print("|"); 13 | 14 | foreach(int a in array){ 15 | print(a); 16 | print("|"); 17 | } 18 | 19 | globalArray[0] = 2; 20 | globalArray[1] = globalArray[0]; 21 | 22 | foreach(int a in globalArray){ 23 | print(a); 24 | print("|"); 25 | } 26 | 27 | test(array); 28 | test(globalArray); 29 | } 30 | 31 | void test(int[] parameterArray){ 32 | parameterArray[0] = 4; 33 | parameterArray[2] = 9; 34 | parameterArray[3] = parameterArray[2]; 35 | 36 | print(parameterArray[0]); 37 | print("|"); 38 | print(parameterArray[3]); 39 | print("|"); 40 | 41 | foreach(int test in parameterArray){ 42 | print(test); 43 | print("|"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /include/ast/Literal.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_LITERAL_H 9 | #define AST_LITERAL_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class Literal 19 | * \brief The AST node for a string literal. 20 | */ 21 | struct Literal { 22 | std::string value; 23 | std::string label; 24 | 25 | Literal(){} 26 | Literal(std::string value) : value(value) {} 27 | }; 28 | 29 | } //end of ast 30 | 31 | } //end of eddic 32 | 33 | //Adapt the struct for the AST 34 | BOOST_FUSION_ADAPT_STRUCT( 35 | eddic::ast::Literal, 36 | (std::string, value) 37 | ) 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/mtac/local_cse.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_LOCAL_CSE_H 9 | #define MTAC_LOCAL_CSE_H 10 | 11 | #include "mtac/pass_traits.hpp" 12 | #include "mtac/forward.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct local_cse { 19 | bool operator()(mtac::Function& function); 20 | }; 21 | 22 | template<> 23 | struct pass_traits { 24 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 25 | STATIC_STRING(name, "local_cse"); 26 | STATIC_CONSTANT(unsigned int, property_flags, 0); 27 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 28 | }; 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/asm/IntelAssemblyUtils.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "asm/IntelAssemblyUtils.hpp" 9 | 10 | #include "AssemblyFileWriter.hpp" 11 | 12 | using namespace eddic; 13 | 14 | void eddic::as::save(AssemblyFileWriter& writer, const std::vector& registers){ 15 | for(auto& reg : registers){ 16 | writer.stream() << "push " << reg << '\n'; 17 | } 18 | } 19 | 20 | void eddic::as::restore(AssemblyFileWriter& writer, const std::vector& registers){ 21 | auto it = registers.rbegin(); 22 | auto end = registers.rend(); 23 | 24 | while(it != end){ 25 | writer.stream() << "pop " << *it << '\n'; 26 | ++it; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /include/Assembler.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ASSEMBLER_H 9 | #define ASSEMBLER_H 10 | 11 | #include 12 | 13 | #include "Platform.hpp" 14 | 15 | namespace eddic { 16 | 17 | /*! 18 | * \brief Assemble and link the output.asm file and procude the output executable. 19 | * \param platform The target platform. 20 | * \param output The output file path. 21 | * \param debug The debug mode flag. 22 | * \param verbose The verbose mode flag. 23 | */ 24 | void assemble(Platform platform, const std::string& s, const std::string& o, const std::string& output, bool debug, bool verbose); 25 | 26 | void verify_dependencies(); 27 | 28 | } //end of eddic 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/documentation.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #error Documentation only 9 | 10 | /*! 11 | * \mainpage 12 | * 13 | * \section Introduction 14 | * 15 | * This page describes the EDDI Compiler. 16 | * 17 | * \section Compilation phases 18 | * 19 | * The EDDI compiler works in several phases. 20 | * 21 | * \li Parse the provided file using a recursive descent LL Parser into an Abstract Syntax Tree (AST) 22 | * \li Checks the AST 23 | * \li Optimize the AST 24 | * \li Compile the AST into a machine-independent instruction set 25 | * \li Compile the instruction set into machine assembly 26 | * \li If activated, assemble and link the assembly into an executable 27 | */ 28 | -------------------------------------------------------------------------------- /src/statistics.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "statistics.hpp" 9 | 10 | using namespace eddic; 11 | 12 | void statistics::inc_counter(const std::string& a){ 13 | ++counters[a]; 14 | } 15 | 16 | std::size_t statistics::counter(const std::string& a) const { 17 | return counters.at(a); 18 | } 19 | 20 | std::size_t statistics::counter_safe(const std::string& a) const { 21 | if (counters.contains(a)) { 22 | return counters.at(a); 23 | } 24 | 25 | return 0; 26 | } 27 | 28 | statistics::iterator statistics::begin() const { 29 | return counters.cbegin(); 30 | } 31 | 32 | statistics::iterator statistics::end() const { 33 | return counters.cend(); 34 | } 35 | -------------------------------------------------------------------------------- /include/ast/PrefixOperation.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_PREFIX_OPERATION_H 9 | #define AST_PREFIX_OPERATION_H 10 | 11 | #include 12 | 13 | #include "ast/Operator.hpp" 14 | #include "ast/Value.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace ast { 19 | 20 | struct PrefixOperation: x3::file_position_tagged { 21 | Value left_value; 22 | ast::Operator op; 23 | 24 | }; 25 | 26 | } //end of ast 27 | 28 | } //end of eddic 29 | 30 | //Adapt the struct for the AST 31 | BOOST_FUSION_ADAPT_STRUCT( 32 | eddic::ast::PrefixOperation, 33 | (eddic::ast::Operator, op) 34 | (eddic::ast::Value, left_value) 35 | ) 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/SemanticalException.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "SemanticalException.hpp" 13 | 14 | using namespace eddic; 15 | 16 | SemanticalException::SemanticalException(std::string message) : m_message(std::move(message)) {} 17 | 18 | SemanticalException::~SemanticalException() throw() {} 19 | 20 | const char* SemanticalException::what() const throw() { 21 | return m_message.c_str(); 22 | } 23 | 24 | const std::string& SemanticalException::message() const { 25 | return m_message; 26 | } 27 | 28 | void eddic::output_exception(const SemanticalException& e){ 29 | std::cout << e.what() << std::endl; 30 | } 31 | -------------------------------------------------------------------------------- /test/cases/inc.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void main(){ 4 | test_int(); 5 | test_arrays(); 6 | } 7 | 8 | void test_int(){ 9 | int a = 0; 10 | print(a); 11 | print("|"); 12 | 13 | a++; 14 | print(a); 15 | print("|"); 16 | 17 | ++a; 18 | print(a); 19 | print("|"); 20 | 21 | --a; 22 | print(a); 23 | print("|"); 24 | 25 | a--; 26 | print(a); 27 | print("|"); 28 | 29 | int b = ++a; 30 | print(b); 31 | print("|"); 32 | 33 | b = a++; 34 | print(b); 35 | print("|"); 36 | } 37 | 38 | void test_arrays(){ 39 | int array[3]; 40 | 41 | ++array[2]; 42 | print(array[2]); 43 | print("|"); 44 | 45 | print(array[2]++); 46 | print("|"); 47 | 48 | print(array[2]); 49 | print("|"); 50 | 51 | --array[2]; 52 | print(array[2]); 53 | print("|"); 54 | 55 | print(array[2]--); 56 | print("|"); 57 | 58 | print(array[2]); 59 | print("|"); 60 | } 61 | -------------------------------------------------------------------------------- /include/mtac/pure_analysis.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_PURE_ANALYSIS_H 9 | #define MTAC_PURE_ANALYSIS_H 10 | 11 | #include "mtac/pass_traits.hpp" 12 | #include "mtac/forward.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct pure_analysis { 19 | bool operator()(mtac::Program& program); 20 | }; 21 | 22 | template<> 23 | struct pass_traits { 24 | STATIC_CONSTANT(pass_type, type, pass_type::IPA); 25 | STATIC_STRING(name, "pure_analysis"); 26 | STATIC_CONSTANT(unsigned int, property_flags, 0); 27 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 28 | }; 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/ast/IntegerSuffix.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_INTEGER_SUFFIX_H 9 | #define AST_INTEGER_SUFFIX_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace eddic { 16 | 17 | namespace ast { 18 | 19 | /*! 20 | * \class IntegerSuffix 21 | * \brief The AST node for an integer suffixed to be another type. 22 | */ 23 | struct IntegerSuffix { 24 | int value; 25 | std::string suffix; 26 | }; 27 | 28 | } //end of ast 29 | 30 | } //end of eddic 31 | 32 | //Adapt the struct for the AST 33 | BOOST_FUSION_ADAPT_STRUCT( 34 | eddic::ast::IntegerSuffix, 35 | (int, value) 36 | (std::string, suffix) 37 | ) 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/boost_cfg.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef EDDIC_BOOST_CFG_H 9 | #define EDDIC_BOOST_CFG_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace boost { 16 | 17 | BOOST_NORETURN inline void throw_exception( const std::exception & ){ 18 | std::terminate(); 19 | }; 20 | 21 | } // namespace boost 22 | 23 | #define EDDIC_BOOST_LIMIT_SIZE 30 24 | #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 25 | #define BOOST_MPL_LIMIT_VECTOR_SIZE EDDIC_BOOST_LIMIT_SIZE 26 | #define BOOST_MPL_LIMIT_LIST_SIZE EDDIC_BOOST_LIMIT_SIZE 27 | #define BOOST_SPIRIT_USE_PHOENIX_V3 28 | 29 | //#define BOOST_SPIRIT_X3_DEBUG 30 | #define BOOST_SPIRIT_X3_NO_RTTI 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/mtac/loop_analysis.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_LOOP_ANALYSIS_H 9 | #define MTAC_LOOP_ANALYSIS_H 10 | 11 | #include "mtac/pass_traits.hpp" 12 | #include "mtac/forward.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct loop_analysis { 19 | bool operator()(mtac::Function& function); 20 | }; 21 | 22 | template<> 23 | struct pass_traits { 24 | STATIC_STRING(name, "loop_analysis"); 25 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 26 | STATIC_CONSTANT(unsigned int, property_flags, 0); 27 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 28 | }; 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /test/cases/stdlib_string.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | void debug(string a){ 4 | print(a.size()); 5 | print("|"); 6 | 7 | print(a); 8 | print("|"); 9 | } 10 | 11 | void debug_ptr(string* a){ 12 | print(a.size()); 13 | print("|"); 14 | 15 | print(*a); 16 | print("|"); 17 | } 18 | 19 | void main(){ 20 | string a("adsf"); 21 | string b("dddddddd"); 22 | string c("adsf"); 23 | 24 | print(a); 25 | print("|"); 26 | 27 | debug(a); 28 | debug_ptr(&b); 29 | debug_ptr(&c); 30 | debug(c); 31 | 32 | print(a.equals(a)); 33 | print("|"); 34 | print(a.equals(b)); 35 | print("|"); 36 | print(a.equals(c)); 37 | print("|"); 38 | 39 | print(b.equals(a)); 40 | print("|"); 41 | print(b.equals(b)); 42 | print("|"); 43 | print(b.equals(c)); 44 | print("|"); 45 | 46 | print(c.equals(a)); 47 | print("|"); 48 | print(c.equals(b)); 49 | print("|"); 50 | print(c.equals(c)); 51 | print("|"); 52 | } 53 | -------------------------------------------------------------------------------- /include/StopWatch.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef STOP_WATCH_H 9 | #define STOP_WATCH_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | typedef std::chrono::high_resolution_clock Clock; 16 | 17 | /*! 18 | * \class StopWatch 19 | * \brief Simple stopwatch to keep track of elapsed time between two points. 20 | * 21 | * The stopwatch starts automatically when instantiated. This stopwatch use Boost Chrono to keep tracks of time. 22 | */ 23 | class StopWatch { 24 | public: 25 | StopWatch(); 26 | double elapsed(); 27 | double micro_elapsed(); 28 | 29 | private: 30 | Clock::time_point startTime; 31 | }; 32 | 33 | } //end of eddic 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/ast/DefaultValues.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef DEFAULT_VALUES_H 9 | #define DEFAULT_VALUES_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct DefaultValuesPass : Pass { 18 | void apply_program(ast::SourceFile& program, bool indicator) override; 19 | void apply_function(ast::TemplateFunctionDeclaration& function) override; 20 | void apply_struct_function(ast::TemplateFunctionDeclaration& function) override; 21 | void apply_struct_constructor(ast::Constructor& constructor) override; 22 | void apply_struct_destructor(ast::Destructor& destructor) override; 23 | }; 24 | 25 | } //end of ast 26 | 27 | } //end of eddic 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /test/cases/member_functions_param_stack.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct Counter { 4 | int value; 5 | 6 | void increment(){ 7 | this.value = this.value + 1; 8 | } 9 | 10 | void add(int number){ 11 | this.value = this.value + number; 12 | } 13 | 14 | void add(int n1, int n2){ 15 | this.value = this.value + n1; 16 | this.value = this.value + n2; 17 | } 18 | 19 | void addSub(int n1, int n2){ 20 | this.add(n1); 21 | this.add(n2); 22 | } 23 | } 24 | 25 | void main(){ 26 | Counter counter; 27 | test(counter); 28 | } 29 | 30 | void test(Counter counter){ 31 | print(counter.value); 32 | print("|"); 33 | counter.increment(); 34 | print(counter.value); 35 | print("|"); 36 | counter.add(99); 37 | print(counter.value); 38 | print("|"); 39 | counter.add(11, 69); 40 | print(counter.value); 41 | print("|"); 42 | counter.addSub(11, 69); 43 | print(counter.value); 44 | print("|"); 45 | } 46 | -------------------------------------------------------------------------------- /include/Platform.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef PLATFORM_H 9 | #define PLATFORM_H 10 | 11 | #include "PlatformDescriptor.hpp" 12 | 13 | namespace eddic { 14 | 15 | /*! 16 | * \enum Platform 17 | * \brief A type of platform. 18 | */ 19 | enum class Platform : unsigned int { 20 | INTEL_X86 = 0, 21 | INTEL_X86_64 = 1 22 | }; 23 | 24 | constexpr inline unsigned int number_of_platform = 2; 25 | 26 | /*! 27 | * \brief Return the platform descriptor of the specified platform. 28 | * \param platform The platform identifier 29 | * \return The platform descriptor of the given platform. 30 | */ 31 | const PlatformDescriptor* getPlatformDescriptor(Platform platform); 32 | 33 | } //end of eddic 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/ltac/forward.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_FORWARD_DECLARATIONS_H 9 | #define LTAC_FORWARD_DECLARATIONS_H 10 | 11 | #include 12 | 13 | #include "variant.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace ltac { 18 | 19 | struct Instruction; 20 | 21 | struct Register; 22 | struct FloatRegister; 23 | struct PseudoRegister; 24 | struct PseudoFloatRegister; 25 | 26 | typedef boost::variant< 27 | ltac::Register, 28 | ltac::PseudoRegister, 29 | ltac::PseudoFloatRegister, //Not used 30 | ltac::FloatRegister> //Not used 31 | AddressRegister; 32 | 33 | struct Address; 34 | 35 | } //end of ltac 36 | 37 | } //end of eddic 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/statistics.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef STATISTICS_H 9 | #define STATISTICS_H 10 | 11 | #include 12 | #include 13 | 14 | namespace eddic { 15 | 16 | class statistics { 17 | public: 18 | using Counters = std::unordered_map; 19 | using iterator = Counters::const_iterator; 20 | 21 | void inc_counter(const std::string& a); 22 | std::size_t counter(const std::string& a) const; 23 | std::size_t counter_safe(const std::string& a) const; 24 | 25 | iterator begin() const; 26 | iterator end() const; 27 | 28 | private: 29 | Counters counters; 30 | }; 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/mtac/remove_aliases.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_REMOVE_ALIASES_H 9 | #define MTAC_REMOVE_ALIASES_H 10 | 11 | #include 12 | 13 | #include "mtac/pass_traits.hpp" 14 | #include "mtac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace mtac { 19 | 20 | struct remove_aliases { 21 | bool operator()(mtac::Function& function); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 27 | STATIC_STRING(name, "remove_aliases"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/asm/CodeGeneratorFactory.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "asm/CodeGeneratorFactory.hpp" 9 | #include "asm/IntelX86CodeGenerator.hpp" 10 | #include "asm/IntelX86_64CodeGenerator.hpp" 11 | 12 | using namespace eddic; 13 | 14 | std::unique_ptr eddic::as::CodeGeneratorFactory::get(Platform platform, AssemblyFileWriter& writer, mtac::Program& program, GlobalContext & context){ 15 | switch(platform){ 16 | case Platform::INTEL_X86: 17 | return std::make_unique(writer, program, context); 18 | case Platform::INTEL_X86_64: 19 | return std::make_unique(writer, program, context); 20 | } 21 | 22 | return nullptr; 23 | } 24 | -------------------------------------------------------------------------------- /include/mtac/clean_variables.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_CLEAN_VARIABLES_H 9 | #define MTAC_CLEAN_VARIABLES_H 10 | 11 | #include 12 | 13 | #include "mtac/pass_traits.hpp" 14 | #include "mtac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace mtac { 19 | 20 | struct clean_variables { 21 | bool operator()(mtac::Function& function); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 27 | STATIC_STRING(name, "clean_variables"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/mtac/parameter_propagation.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_PARAMETER_PROPAGATION_H 9 | #define MTAC_PARAMETER_PROPAGATION_H 10 | 11 | #include "mtac/pass_traits.hpp" 12 | #include "mtac/forward.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct parameter_propagation { 19 | bool operator()(mtac::Program& program); 20 | }; 21 | 22 | template<> 23 | struct pass_traits { 24 | STATIC_CONSTANT(pass_type, type, pass_type::IPA); 25 | STATIC_STRING(name, "parameter_propagation"); 26 | STATIC_CONSTANT(unsigned int, property_flags, 0); 27 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 28 | }; 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/Parameter.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "Parameter.hpp" 9 | 10 | using namespace eddic; 11 | 12 | Parameter::Parameter(const std::string& name, std::shared_ptr type) : _name(name), _type(type){ 13 | //Nothing to do 14 | } 15 | 16 | Parameter::Parameter(Parameter&& rhs) : _name(std::move(rhs._name)), _type(std::move(rhs._type)) { 17 | //Nothing to do 18 | } 19 | 20 | Parameter& Parameter::operator=(Parameter&& rhs){ 21 | _name = std::move(rhs._name); 22 | _type = std::move(rhs._type); 23 | 24 | return *this; 25 | } 26 | 27 | const std::string& Parameter::name() const { 28 | return _name; 29 | } 30 | 31 | const std::shared_ptr& Parameter::type() const { 32 | return _type; 33 | } 34 | -------------------------------------------------------------------------------- /include/Warnings.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef WARNINGS_H 9 | #define WARNINGS_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | //TODO Warn functions should be moved into the global error handler 16 | 17 | /*! 18 | * \brief Produces a warning on the command line. 19 | * \param warning The warning message to produce. 20 | */ 21 | void warn(const std::string& warning); 22 | 23 | /*! 24 | * \brief Produces a warning on the command line and display the source of the warning. 25 | * \param position The position of the warning in the source file. 26 | * \param warning The warning message to produce. 27 | */ 28 | void warn(const std::string& position, const std::string& warning); 29 | 30 | } //end of eddic 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/ast/Ternary.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_TERNARY_H 9 | #define AST_TERNARY_H 10 | 11 | #include 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | /*! 18 | * \class ASTTernary 19 | * \brief The AST node for a ternary operator. 20 | */ 21 | struct Ternary : x3::file_position_tagged { 22 | Value condition; 23 | Value true_value; 24 | Value false_value; 25 | 26 | }; 27 | 28 | } //end of ast 29 | 30 | } //end of eddic 31 | 32 | //Adapt the struct for the AST 33 | BOOST_FUSION_ADAPT_STRUCT( 34 | eddic::ast::Ternary, 35 | (eddic::ast::Value, condition) 36 | (eddic::ast::Value, true_value) 37 | (eddic::ast::Value, false_value) 38 | ) 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/ltac/Printer.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_PRINTER_H 9 | #define LTAC_PRINTER_H 10 | 11 | #include 12 | 13 | #include "mtac/forward.hpp" 14 | #include "ltac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace ltac { 19 | 20 | /*! 21 | * \class Printer 22 | * \brief Utility class to print the three-address-code representation on the console. 23 | */ 24 | struct Printer { 25 | void print(mtac::Program& program) const ; 26 | void print(mtac::Function& function) const ; 27 | void print(ltac::Instruction& statement) const ; 28 | }; 29 | 30 | void print_statement(const ltac::Instruction& statement, std::ostream& out = std::cout); 31 | 32 | } //end of ltac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/mtac/remove_empty_functions.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_REMOVE_EMPTY_FUNCTIONS_H 9 | #define MTAC_REMOVE_EMPTY_FUNCTIONS_H 10 | 11 | #include "mtac/pass_traits.hpp" 12 | #include "mtac/forward.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct remove_empty_functions { 19 | bool operator()(mtac::Program& program); 20 | }; 21 | 22 | template<> 23 | struct pass_traits { 24 | STATIC_CONSTANT(pass_type, type, pass_type::IPA); 25 | STATIC_STRING(name, "remove_empty_functions"); 26 | STATIC_CONSTANT(unsigned int, property_flags, 0); 27 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 28 | }; 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/ltac/Argument.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LTAC_ARGUMENT_H 9 | #define LTAC_ARGUMENT_H 10 | 11 | #include 12 | 13 | #include "variant.hpp" 14 | 15 | #include "ltac/forward.hpp" 16 | 17 | namespace eddic { 18 | 19 | namespace ltac { 20 | 21 | typedef boost::variant< 22 | /* Hard Registers */ 23 | eddic::ltac::FloatRegister, eddic::ltac::Register, 24 | /* Pseudo Registers */ 25 | eddic::ltac::PseudoFloatRegister, eddic::ltac::PseudoRegister, 26 | /* Address */ 27 | eddic::ltac::Address, 28 | /* Literals */ 29 | std::string, 30 | /* Constants */ 31 | double, int 32 | > Argument; 33 | 34 | } //end of ltac 35 | 36 | } //end of eddic 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/mtac/ConstantFolding.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_CONSTANT_FOLDING_H 9 | #define MTAC_CONSTANT_FOLDING_H 10 | 11 | #include "mtac/forward.hpp" 12 | #include "mtac/pass_traits.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct ConstantFolding { 19 | bool optimized = false; 20 | 21 | void operator()(mtac::Quadruple& quadruple); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::LOCAL); 27 | STATIC_STRING(name, "constant_folding"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/mtac/dominators.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_DOMINATORS_H 9 | #define MTAC_DOMINATORS_H 10 | 11 | #include 12 | 13 | #include "mtac/forward.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace mtac { 18 | 19 | /*! 20 | * \brief Compute the direct dominator of each basic_block. 21 | * 22 | * The computation is made with the Lengauer and Tarjan algorithm. The algorithm runs 23 | * in O(ma(m, n)) time where a(m, n) is the inverse of the Ackermann's function. 24 | * 25 | * Reference: A Fast Algorithm for finding dominators in a Flowgraph by Thomas Lengauer 26 | * and Roberrt Endre Tarjan 27 | */ 28 | void compute_dominators(mtac::Function& function); 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/mtac/remove_unused_functions.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_REMOVE_UNUSED_FUNCTIONS_H 9 | #define MTAC_REMOVE_UNUSED_FUNCTIONS_H 10 | 11 | #include "mtac/pass_traits.hpp" 12 | #include "mtac/forward.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct remove_unused_functions { 19 | bool operator()(mtac::Program& program); 20 | }; 21 | 22 | template<> 23 | struct pass_traits { 24 | STATIC_CONSTANT(pass_type, type, pass_type::IPA); 25 | STATIC_STRING(name, "remove_unused_functions"); 26 | STATIC_CONSTANT(unsigned int, property_flags, 0); 27 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 28 | }; 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/ast/member_function_collection.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_MEMBER_FUNCTION_COLLECTION_PASS_H 9 | #define AST_MEMBER_FUNCTION_COLLECTION_PASS_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct MemberFunctionCollectionPass : Pass { 18 | void apply_struct(ast::struct_definition& struct_, bool indicator) override; 19 | void apply_struct_function(ast::TemplateFunctionDeclaration& function) override; 20 | void apply_struct_constructor(ast::Constructor& constructor) override; 21 | void apply_struct_destructor(ast::Destructor& destructor) override; 22 | 23 | ast::struct_definition* current_struct; 24 | }; 25 | 26 | } //end of ast 27 | 28 | } //end of eddic 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/mtac/BranchOptimizations.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_BRANCH_OPTIMIZATIONS_H 9 | #define MTAC_BRANCH_OPTIMIZATIONS_H 10 | 11 | #include 12 | 13 | #include "mtac/pass_traits.hpp" 14 | #include "mtac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace mtac { 19 | 20 | struct optimize_branches { 21 | bool operator()(mtac::Function& function); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 27 | STATIC_STRING(name, "optimize_branches"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/mtac/remove_empty_loops.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_REMOVE_EMPTY_LOOPS_H 9 | #define MTAC_REMOVE_EMPTY_LOOPS_H 10 | 11 | #include 12 | 13 | #include "mtac/pass_traits.hpp" 14 | #include "mtac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace mtac { 19 | 20 | struct remove_empty_loops { 21 | bool operator()(mtac::Function& function); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 27 | STATIC_STRING(name, "remove_empty_loops"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/StopWatch.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "StopWatch.hpp" 9 | 10 | using namespace eddic; 11 | 12 | typedef std::chrono::milliseconds milliseconds; 13 | typedef std::chrono::microseconds microseconds; 14 | 15 | StopWatch::StopWatch() { 16 | startTime = Clock::now(); 17 | } 18 | 19 | template 20 | inline double elapsed_time(Clock::time_point& start){ 21 | Clock::time_point endTime = Clock::now(); 22 | Precision ms = std::chrono::duration_cast(endTime - start); 23 | 24 | return ms.count(); 25 | } 26 | 27 | double StopWatch::elapsed() { 28 | return elapsed_time(startTime); 29 | } 30 | 31 | double StopWatch::micro_elapsed() { 32 | return elapsed_time(startTime); 33 | } 34 | -------------------------------------------------------------------------------- /include/mtac/ReduceInStrength.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_REDUCE_IN_STRENGTH_H 9 | #define MTAC_REDUCE_IN_STRENGTH_H 10 | 11 | #include "mtac/forward.hpp" 12 | #include "mtac/pass_traits.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct ReduceInStrength { 19 | bool optimized = false; 20 | 21 | void operator()(mtac::Quadruple& quadruple); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::LOCAL); 27 | STATIC_STRING(name, "strength_reduction"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/ast/MemberDeclaration.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_MEMBER_DECLARATION_H 9 | #define AST_MEMBER_DECLARATION_H 10 | 11 | #include 12 | 13 | #include "ast/VariableType.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace ast { 18 | 19 | /*! 20 | * \class MemberDeclaration 21 | * \brief The AST node for a declaration of a member variable. 22 | */ 23 | struct MemberDeclaration : x3::file_position_tagged { 24 | Type type; 25 | std::string name; 26 | 27 | }; 28 | 29 | } //end of ast 30 | 31 | } //end of eddic 32 | 33 | //Adapt the struct for the AST 34 | BOOST_FUSION_ADAPT_STRUCT( 35 | eddic::ast::MemberDeclaration, 36 | (eddic::ast::Type, type) 37 | (std::string, name) 38 | ) 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/mtac/loop_invariant_code_motion.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_LOOP_INVARIANT_CODE_MOTION_H 9 | #define MTAC_LOOP_INVARIANT_CODE_MOTION_H 10 | 11 | #include "mtac/pass_traits.hpp" 12 | #include "mtac/forward.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct loop_invariant_code_motion { 19 | bool operator()(mtac::Function& function); 20 | }; 21 | 22 | template<> 23 | struct pass_traits { 24 | STATIC_STRING(name, "loop_invariant_motion"); 25 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 26 | STATIC_CONSTANT(unsigned int, property_flags, 0); 27 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 28 | }; 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/mtac/DeadCodeElimination.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_DEAD_CODE_ELIMINATION_H 9 | #define MTAC_DEAD_CODE_ELIMINATION_H 10 | 11 | #include 12 | 13 | #include "mtac/pass_traits.hpp" 14 | #include "mtac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace mtac { 19 | 20 | struct dead_code_elimination { 21 | bool operator()(mtac::Function& function); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 27 | STATIC_STRING(name, "dead_code_elimination"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/ltac/Operator.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "ltac/Operator.hpp" 9 | 10 | using namespace eddic; 11 | using eddic::ltac::Operator; 12 | 13 | bool ltac::erase_result(ltac::Operator op){ 14 | return op != Operator::DIV 15 | && ( 16 | op == Operator::MOV 17 | || op == Operator::FMOV 18 | || op == Operator::MUL3 19 | || op == Operator::XOR 20 | || op == Operator::OR 21 | || (op >= Operator::LEA && op <= Operator::CMOVLE) 22 | ); 23 | } 24 | 25 | bool ltac::erase_result_complete(ltac::Operator op){ 26 | return op == Operator::MOV 27 | || op == Operator::FMOV 28 | || op == Operator::LEA 29 | || op == Operator::MUL3; 30 | } 31 | -------------------------------------------------------------------------------- /include/ast/NewArray.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_NEW_ARRAY_H 9 | #define AST_NEW_ARRAY_H 10 | 11 | #include 12 | 13 | #include "ast/VariableType.hpp" 14 | #include "ast/Value.hpp" 15 | 16 | namespace eddic { 17 | 18 | class Context; 19 | 20 | namespace ast { 21 | 22 | /*! 23 | * \class ASTNewArray 24 | * \brief The AST node for a dynamic allocation of array. 25 | */ 26 | struct NewArray : x3::file_position_tagged { 27 | Context * context = nullptr; 28 | 29 | Type type; 30 | Value size; 31 | 32 | }; 33 | 34 | } //end of ast 35 | 36 | } //end of eddic 37 | 38 | //Adapt the struct for the AST 39 | BOOST_FUSION_ADAPT_STRUCT( 40 | eddic::ast::NewArray, 41 | (eddic::ast::Type, type) 42 | (eddic::ast::Value, size) 43 | ) 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /include/mtac/ArithmeticIdentities.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_ARITHMETIC_IDENTITIES_H 9 | #define MTAC_ARITHMETIC_IDENTITIES_H 10 | 11 | #include "mtac/forward.hpp" 12 | #include "mtac/pass_traits.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct ArithmeticIdentities { 19 | bool optimized = false; 20 | 21 | void operator()(mtac::Quadruple& quadruple); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::LOCAL); 27 | STATIC_STRING(name, "arithmetic_identities"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/mtac/induction_variable_optimizations.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_LOOP_OPTIMIZATIONS_H 9 | #define MTAC_LOOP_OPTIMIZATIONS_H 10 | 11 | #include "mtac/pass_traits.hpp" 12 | #include "mtac/forward.hpp" 13 | 14 | namespace eddic { 15 | 16 | namespace mtac { 17 | 18 | struct loop_induction_variables_optimization { 19 | bool operator()(mtac::Function& function); 20 | }; 21 | 22 | template<> 23 | struct pass_traits { 24 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 25 | STATIC_STRING(name, "loop_iv_optimization"); 26 | STATIC_CONSTANT(unsigned int, property_flags, 0); 27 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 28 | }; 29 | 30 | } //end of mtac 31 | 32 | } //end of eddic 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/timing.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TIMING_H 9 | #define TIMING_H 10 | 11 | #include 12 | #include 13 | 14 | #include "Options.hpp" 15 | #include "StopWatch.hpp" 16 | 17 | namespace eddic { 18 | 19 | class timing_system { 20 | public: 21 | void register_timing(std::string name, double time); 22 | void display(); 23 | 24 | private: 25 | std::unordered_map timings; 26 | }; 27 | 28 | class timing_timer { 29 | public: 30 | timing_timer(timing_system& system, const std::string& name); 31 | ~timing_timer(); 32 | 33 | private: 34 | timing_system& system; 35 | std::string name; 36 | StopWatch timer; 37 | }; 38 | 39 | } //end of eddic 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/mtac/Program.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "cpp_utils/assert.hpp" 9 | 10 | #include "Function.hpp" 11 | 12 | #include "mtac/Program.hpp" 13 | 14 | using namespace eddic; 15 | 16 | mtac::Function& mtac::Program::mtac_function(const eddic::Function& function){ 17 | for(auto& f : functions){ 18 | if(f.definition() == function){ 19 | return f; 20 | } 21 | } 22 | 23 | cpp_unreachable(("There are no function \"" + function.mangled_name() + "\"").c_str()); 24 | } 25 | 26 | std::ostream& mtac::operator<<(std::ostream& stream, mtac::Program& program){ 27 | stream << "TAC Program " << std::endl << std::endl; 28 | 29 | for(auto& function : program.functions){ 30 | stream << function; 31 | } 32 | 33 | return stream; 34 | } 35 | -------------------------------------------------------------------------------- /test/cases/ctor_dtor_stack.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int ga = 100; 4 | 5 | struct A { 6 | int a; 7 | 8 | this(){ 9 | this.a = 0; 10 | 11 | print("CA"); 12 | print("|"); 13 | } 14 | 15 | this(str a){ 16 | print("CAS"); 17 | print("|"); 18 | 19 | print(a); 20 | print("|"); 21 | } 22 | 23 | this(int a){ 24 | this.a = a; 25 | 26 | print("CAI"); 27 | print("|"); 28 | } 29 | 30 | this(int a, int b){ 31 | this.a = a * b; 32 | 33 | print("CAII"); 34 | print("|"); 35 | } 36 | 37 | ~this(){ 38 | print("DA"); 39 | print("|"); 40 | } 41 | 42 | void debug(){ 43 | print(this.a); 44 | print("|"); 45 | } 46 | } 47 | 48 | void main(){ 49 | A a; 50 | a.debug(); 51 | 52 | if(ga == 100){ 53 | A b(55); 54 | b.debug(); 55 | } 56 | 57 | A c(33, ga); 58 | c.debug(); 59 | 60 | if(ga > 90){ 61 | A d("666"); 62 | d.debug(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /include/mtac/conditional_propagation.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_CONDITIONAL_PROPAGATION_H 9 | #define MTAC_CONDITIONAL_PROPAGATION_H 10 | 11 | #include 12 | 13 | #include "mtac/pass_traits.hpp" 14 | #include "mtac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace mtac { 19 | 20 | struct conditional_propagation { 21 | bool operator()(mtac::Function& function); 22 | }; 23 | 24 | template<> 25 | struct pass_traits { 26 | STATIC_CONSTANT(pass_type, type, pass_type::CUSTOM); 27 | STATIC_STRING(name, "conditional_propagation"); 28 | STATIC_CONSTANT(unsigned int, property_flags, 0); 29 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 30 | }; 31 | 32 | } //end of mtac 33 | 34 | } //end of eddic 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/mtac/inlining.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_INLINING_H 9 | #define MTAC_INLINING_H 10 | 11 | #include "Options.hpp" 12 | 13 | #include "mtac/pass_traits.hpp" 14 | #include "mtac/forward.hpp" 15 | 16 | namespace eddic { 17 | 18 | namespace mtac { 19 | 20 | struct inline_functions { 21 | bool gate(std::shared_ptr configuration); 22 | bool operator()(mtac::Program& program); 23 | }; 24 | 25 | template<> 26 | struct pass_traits { 27 | STATIC_CONSTANT(pass_type, type, pass_type::IPA); 28 | STATIC_STRING(name, "inline_functions"); 29 | STATIC_CONSTANT(unsigned int, property_flags, 0); 30 | STATIC_CONSTANT(unsigned int, todo_after_flags, 0); 31 | }; 32 | 33 | } //end of mtac 34 | 35 | } //end of eddic 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/ast/function_collection.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_FUNCTION_COLLECTION_PASS_H 9 | #define AST_FUNCTION_COLLECTION_PASS_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct FunctionCollectionPass : Pass { 18 | void apply_function(ast::TemplateFunctionDeclaration& function) override; 19 | void apply_struct_function(ast::TemplateFunctionDeclaration& function) override; 20 | void apply_struct_constructor(ast::Constructor& constructor) override; 21 | void apply_struct_destructor(ast::Destructor& destructor) override; 22 | 23 | GlobalContext & context; 24 | FunctionCollectionPass(GlobalContext & context) : context(context) {} 25 | }; 26 | 27 | } //end of ast 28 | 29 | } //end of eddic 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /stdlib/math.eddi: -------------------------------------------------------------------------------- 1 | /* 2 | * Standard Library : Math functions 3 | */ 4 | 5 | //Return maximal value between a and b 6 | int max(int a, int b){ 7 | if(a >= b){ 8 | return a; 9 | } 10 | 11 | return b; 12 | } 13 | 14 | //Return minimal value between a and b 15 | int min(int a, int b){ 16 | if(a <= b){ 17 | return a; 18 | } 19 | 20 | return b; 21 | } 22 | 23 | //Return the nth pow of a 24 | int pow(int a, int n){ 25 | //The zeroth power of each number is 1 26 | if(n == 0){ 27 | return 1; 28 | } 29 | 30 | int power = a; 31 | 32 | for(int i = 1; i < n; ++i){ 33 | power *= a; 34 | } 35 | 36 | return power; 37 | } 38 | 39 | //Factorial function 40 | int factorial(int n){ 41 | if(n == 0){ 42 | return 1; 43 | } 44 | 45 | return n * factorial(n - 1); 46 | } 47 | 48 | //Number of digits in the int 49 | int digits(int n){ 50 | int digits = 0; 51 | int number = n; 52 | 53 | while (number != 0) { 54 | number /= 10; 55 | ++digits; 56 | } 57 | 58 | return digits; 59 | } 60 | -------------------------------------------------------------------------------- /test/cases/ctor_dtor_heap.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int ga = 100; 4 | 5 | struct A { 6 | int a; 7 | 8 | this(){ 9 | this.a = 0; 10 | 11 | print("CA"); 12 | print("|"); 13 | } 14 | 15 | this(str a){ 16 | print("CAS"); 17 | print("|"); 18 | 19 | print(a); 20 | print("|"); 21 | } 22 | 23 | this(int a){ 24 | this.a = a; 25 | 26 | print("CAI"); 27 | print("|"); 28 | } 29 | 30 | this(int a, int b){ 31 | this.a = a * b; 32 | 33 | print("CAII"); 34 | print("|"); 35 | } 36 | 37 | ~this(){ 38 | print("DA"); 39 | print("|"); 40 | } 41 | 42 | void debug(){ 43 | print(this.a); 44 | print("|"); 45 | } 46 | } 47 | 48 | void main(){ 49 | A* a = new A(); 50 | a.debug(); 51 | delete a; 52 | 53 | A* b = new A(55); 54 | b.debug(); 55 | delete b; 56 | 57 | A* c = new A(33, ga); 58 | c.debug(); 59 | delete c; 60 | 61 | A* d = new A("666"); 62 | delete d; 63 | } 64 | -------------------------------------------------------------------------------- /test/cases/member_pointers.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct A { 4 | int a; 5 | str b; 6 | } 7 | 8 | void main(){ 9 | A a; 10 | 11 | a.a = 44; 12 | a.b = "44"; 13 | 14 | test(&a.a); 15 | 16 | print(a.a); 17 | print("|"); 18 | 19 | test(&a.b); 20 | 21 | print(a.b); 22 | print("|"); 23 | } 24 | 25 | void test(int* a){ 26 | print(*a); 27 | print("|"); 28 | 29 | int* b = a; 30 | 31 | print(*b); 32 | print("|"); 33 | 34 | *a = 55; 35 | 36 | print(*a); 37 | print("|"); 38 | print(*b); 39 | print("|"); 40 | 41 | *b = 66; 42 | 43 | print(*b); 44 | print("|"); 45 | print(*a); 46 | print("|"); 47 | } 48 | 49 | void test(str* a){ 50 | print(*a); 51 | print("|"); 52 | 53 | str* b = a; 54 | 55 | print(*b); 56 | print("|"); 57 | 58 | *a = "55"; 59 | 60 | print(*a); 61 | print("|"); 62 | print(*b); 63 | print("|"); 64 | 65 | *b = "66"; 66 | 67 | print(*b); 68 | print("|"); 69 | print(*a); 70 | print("|"); 71 | } 72 | -------------------------------------------------------------------------------- /include/ast/New.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_NEW_H 9 | #define AST_NEW_H 10 | 11 | #include 12 | 13 | #include "ast/VariableType.hpp" 14 | #include "ast/Value.hpp" 15 | 16 | namespace eddic { 17 | 18 | class Context; 19 | 20 | namespace ast { 21 | 22 | /*! 23 | * \class New 24 | * \brief The AST node for a dynamic allocation. 25 | */ 26 | struct New: x3::file_position_tagged { 27 | Context * context = nullptr; 28 | std::string mangled_name; 29 | 30 | Type type; 31 | std::vector values; 32 | 33 | }; 34 | 35 | } //end of ast 36 | 37 | } //end of eddic 38 | 39 | //Adapt the struct for the AST 40 | BOOST_FUSION_ADAPT_STRUCT( 41 | eddic::ast::New, 42 | (eddic::ast::Type, type) 43 | (std::vector, values) 44 | ) 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/ast/FunctionParameter.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_FUNCTION_PARAMETER_H 9 | #define AST_FUNCTION_PARAMETER_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "ast/VariableType.hpp" 16 | 17 | namespace eddic { 18 | 19 | namespace ast { 20 | 21 | /*! 22 | * \class FunctionParameter 23 | * \brief The AST node for a function parameter in a function declaration. 24 | */ 25 | struct FunctionParameter { 26 | Type parameterType; 27 | std::string parameterName; 28 | }; 29 | 30 | } //end of ast 31 | 32 | } //end of eddic 33 | 34 | //Adapt the struct for the AST 35 | BOOST_FUSION_ADAPT_STRUCT( 36 | eddic::ast::FunctionParameter, 37 | (eddic::ast::Type, parameterType) 38 | (std::string, parameterName) 39 | ) 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /tools/ci-build.sh: -------------------------------------------------------------------------------- 1 | export CCACHE_DIR=/var/tmp/ccache/ 2 | cmake -DCMAKE_CXX_COMPILER=/usr/lib/ccache/bin/g++ -DCMAKE_C_COMPILER=/usr/lib/ccache/bin/gcc -DCMAKE_BUILD_TYPE=Coverage . 3 | make 4 | 5 | echo "Run the test suite" 6 | ./bin/boosttest--eddic_boost_test --report_level=detailed --report_format=xml --report_sink=test-results.xml 7 | 8 | xsltproc tools/boost-junit.xsl test-results.xml > xunit-results.xml 9 | 10 | echo "Collect the code coverage results" 11 | /media/data/server/bin/gcovr -x -r . > gcov-report.xml 12 | 13 | echo "Analyze the source code with cppcheck" 14 | cppcheck -v --platform=unix64 --std=c++11 --enable=all --xml -I include/ src/ 2> cppcheck-results.xml 15 | 16 | echo "Analyze the source code with RATS" 17 | rats -w 3 --xml src/ include/ > rats-results.xml 18 | 19 | echo "Verify memory usage with Valgrind" 20 | valgrind --xml=yes --xml-file=valgrind-results.xml bin/eddic eddi_samples/asm.eddi 21 | 22 | echo "Send the results to Sonar" 23 | sonar-runner 24 | 25 | echo "Generate the doc" 26 | make doc 27 | 28 | echo "Compress the doc" 29 | cd doc/html/ 30 | tar cvzf doc.tar.gz * 31 | mv doc.tar.gz ../../ 32 | -------------------------------------------------------------------------------- /test/cases/builtin.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | int globalArray[10]; 4 | str globalArrayB[11]; 5 | 6 | const str ccc = "asdfasdfiasdf"; 7 | 8 | void main(){ 9 | print(size(globalArray)); 10 | print("|"); 11 | print(size(globalArrayB)); 12 | print("|"); 13 | 14 | int array[12]; 15 | str arrayB[13]; 16 | 17 | print(size(array)); 18 | print("|"); 19 | print(size(arrayB)); 20 | print("|"); 21 | 22 | test(array); 23 | test(arrayB); 24 | 25 | test(globalArray); 26 | test(globalArrayB); 27 | 28 | print(length("asdf")); 29 | print("|"); 30 | 31 | str value = "idididid"; 32 | print(length(value)); 33 | print("|"); 34 | 35 | print(length(ccc)); 36 | print("|"); 37 | print(length(arrayB[0])); 38 | print("|"); 39 | print(length(test())); 40 | print("|"); 41 | } 42 | 43 | void test(int[] parameterArray){ 44 | print(size(parameterArray)); 45 | print("|"); 46 | } 47 | 48 | void test(str[] parameterArray){ 49 | print(size(parameterArray)); 50 | print("|"); 51 | } 52 | 53 | str test(){ 54 | return "999"; 55 | } 56 | -------------------------------------------------------------------------------- /include/asm/StringConverter.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef STRING_CONVERTER_H 9 | #define STRING_CONVERTER_H 10 | 11 | #include 12 | 13 | #include "ltac/forward.hpp" 14 | 15 | namespace eddic { 16 | 17 | namespace as { 18 | 19 | struct StringConverter { 20 | std::string address_to_string(eddic::ltac::Address& address) const; 21 | std::string register_to_string(eddic::ltac::AddressRegister& reg) const; 22 | 23 | virtual std::string operator()(ltac::Register& reg) const = 0; 24 | virtual std::string operator()(ltac::FloatRegister& reg) const = 0; 25 | virtual std::string operator()(ltac::PseudoRegister& reg) const = 0; 26 | virtual std::string operator()(ltac::PseudoFloatRegister& reg) const = 0; 27 | }; 28 | 29 | } //end of namespace as 30 | 31 | } //end of namespace eddic 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/ast/While.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_WHILE_H 9 | #define AST_WHILE_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "ast/Value.hpp" 17 | 18 | namespace eddic { 19 | 20 | class Context; 21 | 22 | namespace ast { 23 | 24 | /*! 25 | * \class While 26 | * \brief The AST node for a while loop. 27 | */ 28 | struct While { 29 | Context * context = nullptr; 30 | 31 | Value condition; 32 | std::vector instructions; 33 | 34 | }; 35 | 36 | } //end of ast 37 | 38 | } //end of eddic 39 | 40 | //Adapt the struct for the AST 41 | BOOST_FUSION_ADAPT_STRUCT( 42 | eddic::ast::While, 43 | (eddic::ast::Value, condition) 44 | (std::vector, instructions) 45 | ) 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/ast/PointerType.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_POINTER_TYPE_H 9 | #define AST_POINTER_TYPE_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "ast/VariableType.hpp" 17 | 18 | namespace eddic { 19 | 20 | namespace ast { 21 | 22 | /*! 23 | * \struct PointerType 24 | * \brief A pointer type in the AST. 25 | */ 26 | struct PointerType { 27 | ast::Type type; 28 | }; 29 | 30 | bool operator==(const PointerType& a, const PointerType& b); 31 | 32 | std::ostream& operator<<(std::ostream& out, const ast::PointerType& type); 33 | 34 | } //end of ast 35 | 36 | } //end of eddic 37 | 38 | //Adapt the struct for the AST 39 | BOOST_FUSION_ADAPT_STRUCT( 40 | eddic::ast::PointerType, 41 | (eddic::ast::Type, type) 42 | ) 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/ast/Else.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_ELSE_H 9 | #define AST_ELSE_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace eddic { 18 | 19 | class Context; 20 | 21 | namespace ast { 22 | 23 | /*! 24 | * \class Else 25 | * \brief The AST node for an else construction. 26 | */ 27 | struct Else { 28 | Context * context = nullptr; 29 | std::vector instructions; 30 | x3::unused_type fake_; 31 | }; 32 | 33 | } //end of ast 34 | 35 | } //end of eddic 36 | 37 | //Adapt the struct for the AST 38 | BOOST_FUSION_ADAPT_STRUCT( 39 | eddic::ast::Else, 40 | (std::vector, instructions) 41 | (x3::unused_type, fake_) 42 | ) 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/ast/SimpleType.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_SIMPLE_TYPE_H 9 | #define AST_SIMPLE_TYPE_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace eddic { 17 | 18 | namespace ast { 19 | 20 | /*! 21 | * \class SimpleType 22 | * \brief A simple (non-array) type in the AST. 23 | */ 24 | struct SimpleType { 25 | bool const_; 26 | std::string type; 27 | }; 28 | 29 | bool operator==(const SimpleType& a, const SimpleType& b); 30 | 31 | std::ostream& operator<<(std::ostream& out, const ast::SimpleType& type); 32 | 33 | } //end of ast 34 | 35 | } //end of eddic 36 | 37 | //Adapt the struct for the AST 38 | BOOST_FUSION_ADAPT_STRUCT( 39 | eddic::ast::SimpleType, 40 | (bool, const_) 41 | (std::string, type) 42 | ) 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/ast/type_collection.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2024. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_TYPE_COLLECTION_PASS_H 9 | #define AST_TYPE_COLLECTION_PASS_H 10 | 11 | #include 12 | #include 13 | 14 | #include "ast/Pass.hpp" 15 | #include "Type.hpp" 16 | 17 | namespace eddic::ast { 18 | 19 | struct TypeCollectionPass : Pass { 20 | void apply_program(ast::SourceFile& program, bool indicator) override; 21 | void apply_struct(ast::struct_definition & struct_, bool indicator) override; 22 | 23 | GlobalContext & context; 24 | TypeCollectionPass(GlobalContext & context) : context(context) {} 25 | 26 | private: 27 | std::unordered_map> fully_resolved; 28 | std::unordered_set pending; 29 | }; 30 | 31 | } // namespace eddic::ast 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/ast/ElseIf.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_ELSE_IF_H 9 | #define AST_ELSE_IF_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "ast/Value.hpp" 17 | 18 | namespace eddic { 19 | 20 | class Context; 21 | 22 | namespace ast { 23 | 24 | /*! 25 | * \class ElseIf 26 | * \brief The AST node for an else if construction. 27 | */ 28 | struct ElseIf { 29 | Context * context = nullptr; 30 | 31 | Value condition; 32 | std::vector instructions; 33 | }; 34 | 35 | } //end of eddic 36 | 37 | } //end of eddic 38 | 39 | //Adapt the struct for the AST 40 | BOOST_FUSION_ADAPT_STRUCT( 41 | eddic::ast::ElseIf, 42 | (eddic::ast::Value, condition) 43 | (std::vector, instructions) 44 | ) 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/ast/DoWhile.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_DO_WHILE_H 9 | #define AST_DO_WHILE_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "ast/Value.hpp" 17 | 18 | namespace eddic { 19 | 20 | class Context; 21 | 22 | namespace ast { 23 | 24 | /*! 25 | * \class ASTDoWhile 26 | * \brief The AST node for a do while loop. 27 | */ 28 | struct DoWhile { 29 | Context * context = nullptr; 30 | 31 | Value condition; 32 | std::vector instructions; 33 | 34 | }; 35 | 36 | } //end of ast 37 | 38 | } //end of eddic 39 | 40 | //Adapt the struct for the AST 41 | BOOST_FUSION_ADAPT_STRUCT( 42 | eddic::ast::DoWhile, 43 | (std::vector, instructions) 44 | (eddic::ast::Value, condition) 45 | ) 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Baptiste Wicht 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /include/ast/VariablesAnnotator.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef VARIABLES_ANNOTATOR_H 9 | #define VARIABLES_ANNOTATOR_H 10 | 11 | #include "ast/Pass.hpp" 12 | 13 | namespace eddic { 14 | 15 | namespace ast { 16 | 17 | struct VariableAnnotationPass : Pass { 18 | void apply_function(ast::TemplateFunctionDeclaration& function) override; 19 | void apply_struct_function(ast::TemplateFunctionDeclaration& function) override; 20 | void apply_struct_constructor(ast::Constructor& constructor) override; 21 | void apply_struct_destructor(ast::Destructor& destructor) override; 22 | void apply_program(ast::SourceFile& program, bool indicator) override; 23 | 24 | GlobalContext & context; 25 | VariableAnnotationPass(GlobalContext & context) : context(context) {} 26 | }; 27 | 28 | } //end of ast 29 | 30 | } //end of eddic 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/ast/Cast.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_CAST_H 9 | #define AST_CAST_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "ast/VariableType.hpp" 16 | 17 | namespace eddic { 18 | 19 | class Context; 20 | class Type; 21 | 22 | namespace ast { 23 | 24 | /*! 25 | * \class Cast 26 | * \brief The AST node for a cast of a variable to another type. 27 | */ 28 | struct Cast : x3::file_position_tagged { 29 | Context * context = nullptr; 30 | std::shared_ptr resolved_type; 31 | 32 | Type type; 33 | Value value; 34 | }; 35 | 36 | } //end of ast 37 | 38 | } //end of eddic 39 | 40 | //Adapt the struct for the AST 41 | BOOST_FUSION_ADAPT_STRUCT( 42 | eddic::ast::Cast, 43 | (eddic::ast::Type, type) 44 | (eddic::ast::Value, value) 45 | ) 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/ast/VariableValue.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_VARIABLE_VALUE_H 9 | #define AST_VARIABLE_VALUE_H 10 | 11 | #include 12 | #include 13 | 14 | namespace eddic { 15 | 16 | class Context; 17 | class Variable; 18 | 19 | namespace ast { 20 | 21 | /*! 22 | * \class ASTVariableValue 23 | * \brief The AST node for a variable value. 24 | */ 25 | struct VariableValue : x3::file_position_tagged { 26 | Context * context = nullptr; 27 | std::shared_ptr var; 28 | 29 | std::string variableName; 30 | 31 | std::shared_ptr variable() const { 32 | return var; 33 | } 34 | }; 35 | 36 | } //end of ast 37 | 38 | } //end of eddic 39 | 40 | //Adapt the struct for the AST 41 | BOOST_FUSION_ADAPT_STRUCT( 42 | eddic::ast::VariableValue, 43 | (std::string, variableName) 44 | ) 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /test/cases/structures.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | struct Complex { 4 | int imag; 5 | int real; 6 | float d; 7 | bool b; 8 | str s; 9 | } 10 | 11 | void main(){ 12 | Complex c; 13 | c.imag = 222; 14 | c.real = 666; 15 | c.d = 3.23; 16 | c.b = false; 17 | c.s = "asdf"; 18 | 19 | print(c.imag); 20 | print("|"); 21 | print(c.real); 22 | print("|"); 23 | print(c.d); 24 | print("|"); 25 | print(c.b); 26 | print("|"); 27 | print(c.s); 28 | print("|"); 29 | 30 | c.imag += 111; 31 | c.real += 222; 32 | c.d += 1.1; 33 | c.b = true; 34 | c.s = "ertz"; 35 | 36 | print(c.imag); 37 | print("|"); 38 | print(c.real); 39 | print("|"); 40 | print(c.d); 41 | print("|"); 42 | print(c.b); 43 | print("|"); 44 | print(c.s); 45 | print("|"); 46 | 47 | test(c); 48 | } 49 | 50 | //Test passing by value 51 | 52 | void test(Complex a){ 53 | print(a.imag); 54 | print("|"); 55 | print(a.real); 56 | print("|"); 57 | print(a.d); 58 | print("|"); 59 | print(a.b); 60 | print("|"); 61 | print(a.s); 62 | print("|"); 63 | } 64 | -------------------------------------------------------------------------------- /test/cases/copy_constructors.eddi: -------------------------------------------------------------------------------- 1 | include 2 | 3 | //Struct with a copy constructor 4 | struct With { 5 | int a; 6 | int b; 7 | 8 | this(){} 9 | 10 | this(With* rhs){ 11 | a = rhs.a; 12 | b = rhs.b; 13 | } 14 | } 15 | 16 | //Struct without a copy constructor 17 | struct Without { 18 | int a; 19 | int b; 20 | } 21 | 22 | void main(){ 23 | with(); 24 | without(); 25 | } 26 | 27 | void with(){ 28 | With a; 29 | a.a = 9; 30 | a.b = 5; 31 | 32 | With b = a; 33 | 34 | print(b.a); 35 | print("|"); 36 | print(b.b); 37 | print("|"); 38 | 39 | a.a = 99; 40 | a.b = 55; 41 | 42 | With c; 43 | c = a; 44 | 45 | print(c.a); 46 | print("|"); 47 | print(c.b); 48 | print("|"); 49 | } 50 | 51 | void without(){ 52 | Without a; 53 | a.a = 9; 54 | a.b = 5; 55 | 56 | Without b = a; 57 | 58 | print(b.a); 59 | print("|"); 60 | print(b.b); 61 | print("|"); 62 | 63 | a.a = 99; 64 | a.b = 55; 65 | 66 | Without c; 67 | c = a; 68 | 69 | print(c.a); 70 | print("|"); 71 | print(c.b); 72 | print("|"); 73 | } 74 | -------------------------------------------------------------------------------- /include/ast/SwitchCase.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef AST_SWITCH_CASE_H 9 | #define AST_SWITCH_CASE_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "ast/Value.hpp" 17 | 18 | namespace eddic { 19 | 20 | class Context; 21 | 22 | namespace ast { 23 | 24 | /*! 25 | * \class SwitchCase 26 | * \brief The AST node for a switch case. 27 | */ 28 | struct SwitchCase : x3::file_position_tagged { 29 | Context * context = nullptr; 30 | 31 | Value value; 32 | std::vector instructions; 33 | }; 34 | 35 | } //end of ast 36 | 37 | } //end of eddic 38 | 39 | //Adapt the struct for the AST 40 | BOOST_FUSION_ADAPT_STRUCT( 41 | eddic::ast::SwitchCase, 42 | (eddic::ast::Value, value) 43 | (std::vector, instructions) 44 | ) 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/mtac/VariableReplace.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2011-2016. 3 | // Distributed under the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MTAC_VARIABLE_REPLACE_H 9 | #define MTAC_VARIABLE_REPLACE_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "mtac/forward.hpp" 17 | #include "mtac/Argument.hpp" 18 | 19 | namespace eddic { 20 | 21 | class Variable; 22 | 23 | namespace mtac { 24 | 25 | typedef std::unordered_map, mtac::Argument> VariableClones; 26 | 27 | struct VariableReplace { 28 | VariableClones& clones; 29 | 30 | VariableReplace(VariableClones& clones) : clones(clones) {} 31 | 32 | void update_usage(mtac::Argument& value); 33 | void update_usage_optional(boost::optional& opt); 34 | 35 | void replace(mtac::Quadruple& quadruple); 36 | }; 37 | 38 | } //end of mtac 39 | 40 | } //end of eddic 41 | 42 | #endif 43 | --------------------------------------------------------------------------------