@ -1,5 +1,6 @@
# include "molasses/parser_primitives.h"
# include "molasses/parser_primitives.h"
# include "molasses/generator_primitives.h"
# include "molasses/generator_primitives.h"
# include "molasses/errors.h"
namespace molasses {
namespace molasses {
@ -117,21 +118,6 @@ namespace molasses {
return builder . str ( ) ;
return builder . str ( ) ;
}
}
// TODO: move to a platform independent file
parser_context register_integers ( parser_context ctx )
{
ctx . types . push_back ( std : : make_shared < primitive_type > ( " i8 " , 1 ) ) ;
ctx . types . push_back ( std : : make_shared < primitive_type > ( " i16 " , 2 ) ) ;
ctx . types . push_back ( std : : make_shared < primitive_type > ( " i32 " , 4 ) ) ;
ctx . types . push_back ( std : : make_shared < primitive_type > ( " i64 " , 8 ) ) ;
ctx . types . push_back ( std : : make_shared < primitive_type > ( " u8 " , 1 ) ) ;
ctx . types . push_back ( std : : make_shared < primitive_type > ( " u16 " , 2 ) ) ;
ctx . types . push_back ( std : : make_shared < primitive_type > ( " u32 " , 4 ) ) ;
ctx . types . push_back ( std : : make_shared < primitive_type > ( " u64 " , 8 ) ) ;
return ctx ;
}
template < >
template < >
parser_context register_i32_operations < architecture_t : : x86_64_linux > ( parser_context ctx ) {
parser_context register_i32_operations < architecture_t : : x86_64_linux > ( parser_context ctx ) {
ctx . operations . emplace_back (
ctx . operations . emplace_back (
@ -150,7 +136,7 @@ namespace molasses {
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
if ( not std : : holds_alternative < int32_t > ( value_a ) or not std : : holds_alternative < int32_t > ( value_b ) ) {
if ( not std : : holds_alternative < int32_t > ( value_a ) or not std : : holds_alternative < int32_t > ( value_b ) ) {
c1">// TODO: handle errors
k">throw interpreter_error ( " + expects i32 i32 as input " ) ;
}
}
current_stack . emplace ( get < int32_t > ( value_a ) + get < int32_t > ( value_b ) ) ;
current_stack . emplace ( get < int32_t > ( value_a ) + get < int32_t > ( value_b ) ) ;
}
}
@ -171,7 +157,7 @@ namespace molasses {
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
if ( not std : : holds_alternative < int64_t > ( value_a ) or not std : : holds_alternative < int64_t > ( value_b ) ) {
if ( not std : : holds_alternative < int64_t > ( value_a ) or not std : : holds_alternative < int64_t > ( value_b ) ) {
c1">// TODO: handle errors
k">throw interpreter_error ( " +_i64 expects i64 i64 as input " ) ;
}
}
current_stack . emplace ( get < int64_t > ( value_a ) + get < int64_t > ( value_b ) ) ;
current_stack . emplace ( get < int64_t > ( value_a ) + get < int64_t > ( value_b ) ) ;
}
}
@ -194,7 +180,9 @@ namespace molasses {
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
if ( not std : : holds_alternative < int64_t > ( value_a ) or not std : : holds_alternative < int64_t > ( value_b ) ) {
if ( not std : : holds_alternative < int64_t > ( value_a ) or not std : : holds_alternative < int64_t > ( value_b ) ) {
// TODO: handle errors
throw interpreter_error ( " /%_i64 expects i64 i64 as input " ) ;
} else if ( get < int64_t > ( value_b ) = = 0 ) {
throw interpreter_error ( " /%_i64 division by zero " ) ;
}
}
current_stack . emplace ( get < int64_t > ( value_a ) / get < int64_t > ( value_b ) ) ;
current_stack . emplace ( get < int64_t > ( value_a ) / get < int64_t > ( value_b ) ) ;
current_stack . emplace ( get < int64_t > ( value_a ) % get < int64_t > ( value_b ) ) ;
current_stack . emplace ( get < int64_t > ( value_a ) % get < int64_t > ( value_b ) ) ;
@ -211,7 +199,7 @@ namespace molasses {
[ ] ( const generate_context & , interpreter_stack & current_stack ) {
[ ] ( const generate_context & , interpreter_stack & current_stack ) {
auto value = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value = current_stack . top ( ) ; current_stack . pop ( ) ;
if ( not std : : holds_alternative < ptr_type > ( value ) & & not ( get < ptr_type > ( value ) . pointed - > name ( ) = = " u8 ptr " ) ) {
if ( not std : : holds_alternative < ptr_type > ( value ) & & not ( get < ptr_type > ( value ) . pointed - > name ( ) = = " u8 ptr " ) ) {
c1">// TODO: handle errors
k">throw interpreter_error ( " u8-ptr_to_i64 expects u8 ptr as input " ) ;
}
}
current_stack . emplace ( intptr_t ( get < ptr_type > ( value ) . ptr ) ) ;
current_stack . emplace ( intptr_t ( get < ptr_type > ( value ) . ptr ) ) ;
}
}
@ -233,7 +221,7 @@ namespace molasses {
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
if ( not std : : holds_alternative < int32_t > ( value_a ) or not std : : holds_alternative < int32_t > ( value_b ) ) {
if ( not std : : holds_alternative < int32_t > ( value_a ) or not std : : holds_alternative < int32_t > ( value_b ) ) {
c1">// TODO: handle errors
k">throw interpreter_error ( " * expects i32 i32 as input " ) ;
}
}
current_stack . emplace ( get < int32_t > ( value_a ) * get < int32_t > ( value_b ) ) ;
current_stack . emplace ( get < int32_t > ( value_a ) * get < int32_t > ( value_b ) ) ;
}
}
@ -255,7 +243,7 @@ namespace molasses {
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_a = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value_b = current_stack . top ( ) ; current_stack . pop ( ) ;
if ( not std : : holds_alternative < int32_t > ( value_a ) or not std : : holds_alternative < int32_t > ( value_b ) ) {
if ( not std : : holds_alternative < int32_t > ( value_a ) or not std : : holds_alternative < int32_t > ( value_b ) ) {
c1">// TODO: handle errors
k">throw interpreter_error ( " - expects i32 i32 as input " ) ;
}
}
current_stack . emplace ( get < int32_t > ( value_a ) - get < int32_t > ( value_b ) ) ;
current_stack . emplace ( get < int32_t > ( value_a ) - get < int32_t > ( value_b ) ) ;
}
}
@ -274,7 +262,7 @@ namespace molasses {
[ ] ( const generate_context & , interpreter_stack & current_stack ) {
[ ] ( const generate_context & , interpreter_stack & current_stack ) {
auto value = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value = current_stack . top ( ) ; current_stack . pop ( ) ;
if ( not std : : holds_alternative < int32_t > ( value ) ) {
if ( not std : : holds_alternative < int32_t > ( value ) ) {
c1">// TODO: handle errors
k">throw interpreter_error ( " i32-to-i64 expects i32 as input " ) ;
}
}
current_stack . emplace ( int64_t ( get < int32_t > ( value ) ) ) ;
current_stack . emplace ( int64_t ( get < int32_t > ( value ) ) ) ;
}
}
@ -292,7 +280,7 @@ namespace molasses {
[ ] ( const generate_context & , interpreter_stack & current_stack ) {
[ ] ( const generate_context & , interpreter_stack & current_stack ) {
auto value = current_stack . top ( ) ; current_stack . pop ( ) ;
auto value = current_stack . top ( ) ; current_stack . pop ( ) ;
if ( not std : : holds_alternative < int64_t > ( value ) ) {
if ( not std : : holds_alternative < int64_t > ( value ) ) {
c1">// TODO: handle errors
k">throw interpreter_error ( " i32-to-i64 expects i32 as input " ) ;
}
}
}
}
)
)
@ -316,7 +304,7 @@ namespace molasses {
not std : : holds_alternative < int64_t > ( value_0 ) or
not std : : holds_alternative < int64_t > ( value_0 ) or
not std : : holds_alternative < int64_t > ( value_1 )
not std : : holds_alternative < int64_t > ( value_1 )
) {
) {
c1">// TODO: handle errors
k">throw interpreter_error ( " syscall1 expects i64 i64 as input " ) ;
}
}
# ifdef linux
# ifdef linux
unix_system : : syscall1 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) ) ;
unix_system : : syscall1 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) ) ;
@ -345,7 +333,7 @@ namespace molasses {
not std : : holds_alternative < int64_t > ( value_1 ) or
not std : : holds_alternative < int64_t > ( value_1 ) or
not std : : holds_alternative < int64_t > ( value_2 )
not std : : holds_alternative < int64_t > ( value_2 )
) {
) {
c1">// TODO: handle errors
k">throw interpreter_error ( " syscall2 expects i64 i64 i64 as input " ) ;
}
}
# ifdef linux
# ifdef linux
unix_system : : syscall2 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) , get < int64_t > ( value_2 ) ) ;
unix_system : : syscall2 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) , get < int64_t > ( value_2 ) ) ;
@ -377,7 +365,7 @@ namespace molasses {
not std : : holds_alternative < int64_t > ( value_2 ) or
not std : : holds_alternative < int64_t > ( value_2 ) or
not std : : holds_alternative < int64_t > ( value_3 )
not std : : holds_alternative < int64_t > ( value_3 )
) {
) {
c1">// TODO: handle errors
k">throw interpreter_error ( " syscall3 expects i64 i64 i64 i64 as input " ) ;
}
}
# ifdef linux
# ifdef linux
unix_system : : syscall3 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) , get < int64_t > ( value_2 ) , get < int64_t > ( value_3 ) ) ;
unix_system : : syscall3 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) , get < int64_t > ( value_2 ) , get < int64_t > ( value_3 ) ) ;
@ -412,7 +400,7 @@ namespace molasses {
not std : : holds_alternative < int64_t > ( value_3 ) or
not std : : holds_alternative < int64_t > ( value_3 ) or
not std : : holds_alternative < int64_t > ( value_4 )
not std : : holds_alternative < int64_t > ( value_4 )
) {
) {
c1">// TODO: handle errors
k">throw interpreter_error ( " syscall4 expects i64 i64 i64 i64 i64 as input " ) ;
}
}
# ifdef linux
# ifdef linux
unix_system : : syscall4 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) , get < int64_t > ( value_2 ) , get < int64_t > ( value_3 ) , get < int64_t > ( value_4 ) ) ;
unix_system : : syscall4 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) , get < int64_t > ( value_2 ) , get < int64_t > ( value_3 ) , get < int64_t > ( value_4 ) ) ;
@ -450,7 +438,7 @@ namespace molasses {
not std : : holds_alternative < int64_t > ( value_4 ) or
not std : : holds_alternative < int64_t > ( value_4 ) or
not std : : holds_alternative < int64_t > ( value_5 )
not std : : holds_alternative < int64_t > ( value_5 )
) {
) {
c1">// TODO: handle errors
k">throw interpreter_error ( " syscall5 expects i64 i64 i64 i64 i64 i64 as input " ) ;
}
}
# ifdef linux
# ifdef linux
unix_system : : syscall5 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) , get < int64_t > ( value_2 ) , get < int64_t > ( value_3 ) , get < int64_t > ( value_4 ) , get < int64_t > ( value_5 ) ) ;
unix_system : : syscall5 { } ( get < int64_t > ( value_0 ) , get < int64_t > ( value_1 ) , get < int64_t > ( value_2 ) , get < int64_t > ( value_3 ) , get < int64_t > ( value_4 ) , get < int64_t > ( value_5 ) ) ;
@ -491,7 +479,7 @@ namespace molasses {
not std : : holds_alternative < int64_t > ( value_5 ) or
not std : : holds_alternative < int64_t > ( value_5 ) or
not std : : holds_alternative < int64_t > ( value_6 )
not std : : holds_alternative < int64_t > ( value_6 )
) {
) {
c1">// TODO: handle errors
k">throw interpreter_error ( " syscall6 expects i64 i64 i64 i64 i64 i64 i64 as input " ) ;
}
}
# ifdef linux
# ifdef linux
unix_system : : syscall6 { } (
unix_system : : syscall6 { } (