Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: |
|
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
397f594186b2149627a0458f876107eb |
| User & Date: | achavasse 2020-05-17 17:30:43.734 |
Context
|
2020-05-18
| ||
| 12:39 |
| |
|
2020-05-17
| ||
| 17:30 |
| |
|
2020-05-16
| ||
| 19:32 | Repo: fix syntax highlighting with the latest trunk verison of fossil. check-in: 807a4f208b user: achavasse tags: trunk | |
Changes
Changes to bs/builtins/api/compiler.cpp.
| ︙ | ︙ | |||
121 122 123 124 125 126 127 |
RegisterBuiltinFunc< Intrinsic< uint32_t ( string ) > >( e, "#Include"_sid,
[pEnv]( auto&& c, const Value& fnameval ) -> Value
{
auto filename = *FromValue< string >( fnameval );
auto identity = InjectDomainIntoIdentity( RootIdentity(), DomainCompileTime() );
| | > | | > | | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
RegisterBuiltinFunc< Intrinsic< uint32_t ( string ) > >( e, "#Include"_sid,
[pEnv]( auto&& c, const Value& fnameval ) -> Value
{
auto filename = *FromValue< string >( fnameval );
auto identity = InjectDomainIntoIdentity( RootIdentity(), DomainCompileTime() );
auto result = Compiler::LoadAndExecuteFile( pEnv.lock(), filename, identity,
GetValueType< uint32_t >(), ToValue< uint32_t >( 0 ) );
if( !result )
return ToValue< uint32_t >( 0 );
return *result;
} );
RegisterBuiltinFunc< uint32_t ( string ) >( e, "ExecuteFile"_sid,
[pEnv]( const string& filename ) -> Value
{
auto identity = InjectDomainIntoIdentity( RootIdentity(), DomainCompileTime() );
auto result = Compiler::LoadAndExecuteFile( pEnv.lock(), filename, identity,
GetValueType< uint32_t >(), ToValue< uint32_t >( 0 ) );
if( !result )
return ToValue< uint32_t >( 0 );
return *result;
} );
RegisterBuiltinFunc< Intrinsic< Value ( string, Value, Value, Value ) > >( e, "#CompileFileToFunction"_sid,
[pEnv]( auto&& c, const Value& filenameVal, const Value& rt, const Value& defReturnValue, const Value& params ) -> Value
{
if( !filenameVal.isConstant() )
{
DiagnosticsManager::GetInstance().emitErrorMessage( filenameVal.locationId(),
"#CompileFileToFunction: the expression doesn't evaluate to a constant." );
return PoisonValue();
}
|
| ︙ | ︙ | |||
185 186 187 188 189 190 191 |
c.env()->addVisibilityRule(
InjectDomainIntoIdentity( identity, ANYTERM( _ ) ),
InjectDomainIntoIdentity( funcIdentity, ANYTERM( _ ) ) );
auto func = BuildFunc( localC, ftype, identity, params, nullptr, c );
const auto& pFuncLLR = func.llr();
| | > | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
c.env()->addVisibilityRule(
InjectDomainIntoIdentity( identity, ANYTERM( _ ) ),
InjectDomainIntoIdentity( funcIdentity, ANYTERM( _ ) ) );
auto func = BuildFunc( localC, ftype, identity, params, nullptr, c );
const auto& pFuncLLR = func.llr();
auto cfg = Compiler::LoadAndParseFile( pEnv.lock(), filename, funcIdentity,
ftype.returnType(), defReturnValue );
if( !cfg )
return PoisonValue();
if( cfg->isPoisoned() )
return PoisonValue();
pFuncLLR->body() = cfg;
return ToValue( func );
} );
}
}
|
Changes to bs/builtins/statements/return.cpp.
| ︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
// Emit a terminator with a poison value to avoid the function compilation
// code to complain about a missing return.
cb->emitTerminator( p.resolver()->currentLocation(), llr::Ret( PoisonValue() ) );
cb->poison();
return true;
}
cb->emitTerminator( p.resolver()->currentLocation(), llr::Ret( get< Value >( converted ) ) );
return true;
};
Rule r( handleReturn );
auto ruleVal = ToValue( move( r ) );
auto ruleTerm = ValueToIRExpr( ruleVal );
| > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
// Emit a terminator with a poison value to avoid the function compilation
// code to complain about a missing return.
cb->emitTerminator( p.resolver()->currentLocation(), llr::Ret( PoisonValue() ) );
cb->poison();
return true;
}
cb->emitTerminator( p.resolver()->currentLocation(), llr::Ret( get< Value >( converted ) ) );
return true;
};
Rule r( handleReturn );
auto ruleVal = ToValue( move( r ) );
auto ruleTerm = ValueToIRExpr( ruleVal );
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/compile.cpp.
| ︙ | ︙ | |||
255 256 257 258 259 260 261 |
DiagnosticsManager::GetInstance().emitErrorMessage( r->currentLocation(),
"missing return statement in a function with non-void return type." );
return false;
}
// Implicit return at the end of a void function:
// Emit the cleanups, and the terminator.
| | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
DiagnosticsManager::GetInstance().emitErrorMessage( r->currentLocation(),
"missing return statement in a function with non-void return type." );
return false;
}
// Implicit return at the end of a void function:
// Emit the cleanups, and the terminator.
// TODO: at some point we'll want to check for reachability in the static verifier,
// and either emit the implicit return or declare the code unreachable depending on the result.
// The reachability analysis will have to be done before contract validation, as the
// calls to DestroyValue() may also have requirements to enforce, so we'll need to emit
// the eventual implicit return first.
p.flushValue();
cb->destroyAllLiveValues( localContext );
cb->emitTerminator( r->currentLocation(), llr::Ret() );
|
| ︙ | ︙ |
Changes to bs/compile/compiler.cpp.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include "llvm/Support/TargetSelect.h"
using namespace goose;
using namespace goose::util;
using namespace goose::ir;
using namespace goose::sema;
using namespace goose::diagnostics;
namespace goose::compile
{
Compiler::Compiler( int argc, char** argv ) :
m_pEnv( make_shared< sema::Env >() )
{
llvm::InitLLVM( argc, argv );
string cmdArgs;
for( size_t i = 1; i < static_cast< size_t >( argc ); ++i )
{
if( i > 1 )
cmdArgs = cmdArgs + ' ';
cmdArgs = cmdArgs + argv[i];
}
| > | | | | | | | | > | | > > > > > | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
#include "llvm/Support/TargetSelect.h"
using namespace goose;
using namespace goose::util;
using namespace goose::ir;
using namespace goose::sema;
using namespace goose::diagnostics;
using namespace goose::builtins;
namespace goose::compile
{
Compiler::Compiler( int argc, char** argv ) :
m_pEnv( make_shared< sema::Env >() )
{
llvm::InitLLVM( argc, argv );
string cmdArgs;
for( size_t i = 1; i < static_cast< size_t >( argc ); ++i )
{
if( i > 1 )
cmdArgs = cmdArgs + ' ';
cmdArgs = cmdArgs + argv[i];
}
SetupBuiltins( *m_pEnv );
RegisterBuiltinFunc< string() >( *m_pEnv, "Args"_sid,
[cmdArgs]()
{
return cmdArgs;
} );
RegisterBuiltinFunc< void ( string ) >( *m_pEnv, "Print"_sid,
[]( const string& str )
{
cout << str;
} );
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargets();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmParsers();
llvm::InitializeAllAsmPrinters();
}
uint32_t Compiler::execute( const string& filename )
{
auto identity = sema::InjectDomainIntoIdentity( builtins::RootIdentity(), sema::DomainCompileTime() );
auto result = LoadAndExecuteFile( m_pEnv, filename, identity, GetValueType< uint32_t >(), ToValue< uint32_t >( 1 ) );
if( DiagnosticsManager::GetInstance().errorsWereEmitted() )
return 1;
if( !result )
return 0;
if( result->isPoison() )
return 1;
return *FromValue< uint32_t >( *result );
}
optional< Value > Compiler::LoadAndExecuteFile( const ptr< Env >& e, const string& filename, const Term& identity,
const Term& returnType, optional< Value > defRetVal )
{
auto cfg = LoadAndParseFile( e, filename, identity, returnType, defRetVal );
if( !cfg )
return PoisonValue();
if( !cfg->entryBB()->canBeExecuted() )
{
DiagnosticsManager::GetInstance().emitErrorMessage( 0,
format( "{}: can not be executed.", filename ) );
return PoisonValue();
}
execute::VM vm;
return vm.execute( cfg->entryBB() );
}
ptr< llr::CFG > Compiler::LoadAndParseFile( const ptr< Env >& e, const string& filename, const Term& identity,
const Term& returnType, optional< Value > defRetVal )
{
auto& dm = DiagnosticsManager::GetInstance();
assert( returnType == GetValueType< void >() || defRetVal );
ifstream sourcefile( filename.c_str() );
if( !sourcefile.good() )
{
dm.emitErrorMessage( 0,
format( "can't open '{}'.", filename ) );
return nullptr;
}
sema::Context c( e, identity, returnType );
DiagnosticsContext dc( 0, true );
VerbosityContext vc( Verbosity::Normal, true );
|
| ︙ | ︙ | |||
114 115 116 117 118 119 120 |
p.parseSequence();
if( cfg->isPoisoned() )
return cfg;
if( !r->eos() )
{
| < | > < < < > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
p.parseSequence();
if( cfg->isPoisoned() )
return cfg;
if( !r->eos() )
{
dm.emitSyntaxErrorMessage( r->currentLocation(), "syntax error." );
return nullptr;
}
if( cfg->currentBB() && !cfg->currentBB()->terminator() )
{
p.flushValue();
cb->destroyAllLiveValues( c );
if( returnType == GetValueType< void >() )
cb->emitTerminator( r->currentLocation(), llr::Ret() );
else if( !defRetVal )
{
dm.emitSyntaxErrorMessage( r->currentLocation(), "missing return statement." );
return nullptr;
}
else
{
auto converted = ConvertValueToType( c, *defRetVal, returnType );
if( holds_alternative< ValUnifyError >( converted ) )
{
switch( get< ValUnifyError >( converted ) )
{
case ValUnifyError::NoSolution:
dm.emitErrorMessage( defRetVal->locationId(), "default return value type mismatch." );
break;
case ValUnifyError::Ambiguous:
dm.emitErrorMessage( defRetVal->locationId(), "ambiguous default return value conversion." );
break;
}
return nullptr;
}
cb->emitTerminator( r->currentLocation(), llr::Ret( get< Value >( converted ) ) );
}
}
verify::Func fv( cfg );
if( !fv.verify() )
return nullptr;
return cfg;
}
}
|
Changes to bs/compile/compiler.h.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 |
class Compiler
{
public:
Compiler( int argc, char** argv );
uint32_t execute( const string& filename );
static optional< ir::Value > LoadAndExecuteFile( const util::ptr< sema::Env >& e, const string& filename,
| | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class Compiler
{
public:
Compiler( int argc, char** argv );
uint32_t execute( const string& filename );
static optional< ir::Value > LoadAndExecuteFile( const util::ptr< sema::Env >& e, const string& filename,
const ir::Term& identity, const ir::Term& returnType, optional< ir::Value > defRetVal );
static util::ptr< llr::CFG > LoadAndParseFile( const util::ptr< sema::Env >& e, const string& filename,
const ir::Term& identity, const ir::Term& returnType, optional< ir::Value > defRetVal );
private:
util::ptr< sema::Env > m_pEnv;
};
}
#endif
|
Changes to bs/goose.cpp.
1 2 3 4 5 6 7 8 9 |
#include "compile/compiler.h"
using namespace std;
using namespace goose;
using namespace goose::util;
int main( int argc, char** argv )
{
compile::Compiler ec( argc, argv );
| < | < < < | 1 2 3 4 5 6 7 8 9 10 11 |
#include "compile/compiler.h"
using namespace std;
using namespace goose;
using namespace goose::util;
int main( int argc, char** argv )
{
compile::Compiler ec( argc, argv );
return ec.execute( "lib/goose.g" );
}
|
Changes to lib/frontend.g.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 |
// Create the module
var module = CGModuleCreate( SourceToCompile )
// Setup the target.
if !CGModuleSetupTarget( module )
{
Print( "Failed to setup llvm target.\n" )
| | | < | | | | | > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
// Create the module
var module = CGModuleCreate( SourceToCompile )
// Setup the target.
if !CGModuleSetupTarget( module )
{
Print( "Failed to setup llvm target.\n" )
return 1
}
// Define the exit external function.
using exit = ExternalFunction( void( uint( 32 ) returnCode ), "_exit" )
using main = #CompileFileToFunction( SourceToCompile, uint( 32 ), 0, () )
// The entry point of the binary.
// We have to use "using" and an anonymous function, because otherwise
// it would create an overloadset and CGGenerateFunction wouldn't know
// how to deal with that.
// This is basically the "crt0". Dunno yet if it's a good idea to build it myself
// or just to link to an existing crt0.o. This has the advantage of flexibility
// to add features later on, but may require more compile time conditional magic
// to handle various platforms.
// Right now it has the advantage of avoiding yet another external dependency.
using entryPoint = void() {
exit( main() )
}
if !CGGenerateFunction( module, entryPoint, "_start" )
{
Print( "Frontend: codegen failed.\n" )
return 1
}
// Run the llvm optimization passes
CGModuleOptimize( module )
// Output the llvm ir and the asm for inspection.
CGModuleEmitLLVMIr( module, strcat( SourceToCompile, ".ll" ) )
if !CGModuleEmitAsm( module, strcat( SourceToCompile, ".s" ) )
{
Print( strcat( "Failed to write ", strcat( SourceToCompile, ".s\n" ) ) )
return 1
}
// Output the object file.
if !CGModuleEmitObj( module, strcat( SourceToCompile, ".o" ) )
{
Print( strcat( "Failed to write ", strcat( SourceToCompile, ".o\n" ) ) )
return 1
}
// Link it and produce an executable file.
var linkerArgs = (
strcat( SourceToCompile, ".o" ),
"-o", strcat( SourceToCompile, ".out" ),
"-L/lib/x86_64-linux-gnu", "-lc",
"--dynamic-linker=/lib64/ld-linux-x86-64.so.2"
)
if !CGLinkerELF( linkerArgs )
return 1
Print( strcat( "Built executable ", strcat( SourceToCompile, ".out\n" ) ) )
return 0
|
Name change from tests/noprelude/complex/mandelbrot.g to tests/noprelude/combined/mandelbrot.g.
| ︙ | ︙ |
Name change from tests/noprelude/complex/mandelbrot.txt to tests/noprelude/combined/mandelbrot.txt.
| ︙ | ︙ |
Name change from tests/noprelude/complex/meson.build to tests/noprelude/combined/meson.build.
1 2 3 4 5 6 7 8 9 10 11 12 |
tests = [
'mandelbrot'
]
testrunner_interp = find_program( 'test_runner_interp.sh' )
testrunner_compile = find_program( 'test_runner_compile.sh' )
foreach t : tests
file = configure_file( copy: true,
input: t + '.g', output: t + '.g'
)
| > | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
tests = [
#'tuple', # Not enabled yet since it requires implementing LowerType for tuples to be able to compile
'mandelbrot'
]
testrunner_interp = find_program( 'test_runner_interp.sh' )
testrunner_compile = find_program( 'test_runner_compile.sh' )
foreach t : tests
file = configure_file( copy: true,
input: t + '.g', output: t + '.g'
)
test( 'g-np-combined-interp-' + t, testrunner_interp,
args: [ goose, 'tests/noprelude/combined/' + t,
files( t + '.txt' ) ] )
test( 'g-np-combined-compile-' + t, testrunner_compile,
args: [ goose, 'tests/noprelude/combined/' + t,
files( t + '.txt' ) ] )
endforeach
|
Name change from tests/noprelude/complex/test_runner_compile.sh to tests/noprelude/combined/test_runner_compile.sh.
| ︙ | ︙ |
Name change from tests/noprelude/complex/test_runner_interp.sh to tests/noprelude/combined/test_runner_interp.sh.
| ︙ | ︙ |
Added tests/noprelude/combined/tuple.g.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
using puts = ExternalFunction( uint(32) ( pointer( uint(8) ) str ), "puts" )
void print( ct_string str )
{
#if IsCompiling
{
puts( str )
}
#else
{
Print( str )
}
}
bool check( bool cond, ct_string message )
{
print( message )
print( ": " )
if cond print( "OK\n" ) else print( "Failed\n" )
return cond
}
// Multiple return values
bool, ct_string foo()
{
return true, "lomarf"
}
var tup1 = foo()
if !check( tup1.0 & tup1.1 == "lomarf", "tuple test 1" )
return 1
// Splicing
ct_int, bool, ct_string, ct_string bar()
{
return 219, foo(), "laffo"
}
var tup2 = bar()
if !check( tup2.0 == 219 & tup2.1 & tup2.2 == "lomarf" & tup2.3 == "laffo", "tuple test 2" )
return 1
// Modifying individual tuple members
tup2.2 = "blah"
if !check( tup2.0 == 219 & tup2.1 & tup2.2 == "blah" & tup2.3 == "laffo", "tuple test 3" )
return 1
|
Added tests/noprelude/combined/tuple.txt.
> > > | 1 2 3 | tuple test 1: OK tuple test 2: OK tuple test 3: OK |
Changes to tests/noprelude/execute/arithops.g.
1 2 3 | #Include( "tests/noprelude/helpers.g" ) if !check( 219 + 1337 == 1556, "add test" ) | | | | | < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#Include( "tests/noprelude/helpers.g" )
if !check( 219 + 1337 == 1556, "add test" )
return 1
if !check( 219 - 1337 == -1118, "sub test" )
return 1
if !check( 219 * 1337 == 292803, "mul test" )
return 1
if !check( 1337 / 219 == 6, "div test" )
return 1
if !check( 1337 % 219 == 23, "modulo test" )
return 1
|
Changes to tests/noprelude/execute/bitwiseops.g.
1 2 3 4 5 6 7 8 |
#Include( "tests/noprelude/helpers.g" )
uint( 32 ) lomarf( uint( 32 ) a, uint( 32 ) b )
{
return a ^ b;
}
if !check( lomarf( 0xdeadbeef, 0xabadfeed ) == 0x75004002, "integer bitwise xor test" )
| | | | | | < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#Include( "tests/noprelude/helpers.g" )
uint( 32 ) lomarf( uint( 32 ) a, uint( 32 ) b )
{
return a ^ b;
}
if !check( lomarf( 0xdeadbeef, 0xabadfeed ) == 0x75004002, "integer bitwise xor test" )
return 1
if !check( ( 0xdeadbeef & 0xabadfeed ) == 0x8aadbeed, "bitwise and test" )
return 1
if !check( ( 0xdeadbeef | 0xabadfeed ) == 0xffadfeef, "bitwise or test" )
return 1
if !check( ( 0b110011 ^ 0x2a ) == 0b011001, "bitwise xor test" )
return 1
if !check( 0xdeadbeef << 4 == 0xdeadbeef0, "left shift test" )
return 1
if !check( 0xdeadbeef >> 4 == 0xdeadbee, "right shift test" )
return 1
|
Changes to tests/noprelude/execute/comparisonops.g.
1 2 3 | #Include( "tests/noprelude/helpers.g" ) if !check( true == true, "eq test 1" ) | | | | | | | | | | | | | | | | | | | | | | < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#Include( "tests/noprelude/helpers.g" )
if !check( true == true, "eq test 1" )
return 1
if !check( 219 == 219, "eq test 2" )
return 1
if !check( "lomarf" == "lomarf", "eq test 3" )
return 1
if !check( !( true == false ), "eq test 4" )
return 1
if !check( !( 219 == 1337 ), "eq test 5" )
return 1
if !check( !( "lomarf" == "lmao" ), "eq test 6" )
return 1
if !check( true != false, "neq test 1" )
return 1
if !check( 219 != 1337, "neq test 2" )
return 1
if !check( "lomarf" != "lmao", "neq test 3" )
return 1
if !check( !( true != true ), "neq test 4" )
return 1
if !check( !( 219 != 219 ), "neq test 5" )
return 1
if !check( !( "lomarf" != "lomarf" ), "neq test 6" )
return 1
if !check( 1337 > 219, "gt test 1" )
return 1
if !check( !( 219 > 1337 ), "gt test 2" )
return 1
if !check( 1337 >= 219, "ge test 1" )
return 1
if !check( !( 219 >= 1337 ), "ge test 2" )
return 1
if !check( 1337 >= 1337, "ge test 3" )
return 1
if !check( 219 < 1337, "lt test 1" )
return 1
if !check( !( 1337 < 219 ), "lt test 2" )
return 1
if !check( 219 <= 1337, "le test 1" )
return 1
if !check( !( 1337 <= 219 ), "le test 2" )
return 1
if !check( 1337 <= 1337, "le test 3" )
return 1
|
Changes to tests/noprelude/execute/compoundass.g.
1 2 3 4 5 | #Include( "tests/noprelude/helpers.g" ) var lomarf = 219 if !check( lomarf == 219, "compound assignment operator test 1" ) | | | | | | | | | | | < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#Include( "tests/noprelude/helpers.g" )
var lomarf = 219
if !check( lomarf == 219, "compound assignment operator test 1" )
return 1
lomarf += 1337
if !check( lomarf == 1556, "compound assignment operator test 2" )
return 1
lomarf -= 1337 * 2
if !check( lomarf == -1118, "compound assignment operator test 3" )
return 1
lomarf *= 1337
if !check( lomarf == -1494766, "compound assignment operator test 3" )
return 1
lomarf /= 219
if !check( lomarf == -6825, "compound assignment operator test 4" )
return 1
lomarf = 1337
lomarf %= 219
if !check( lomarf == 23, "compound assignment operator test 5" )
return 1
lomarf = 0xdeadbeef
lomarf ^= 0xabadfeed
if !check( lomarf == 0x75004002, "compound assignment operator test 6" )
return 1
lomarf = 0xdeadbeef
lomarf &= 0xabadfeed
if !check( lomarf == 0x8aadbeed, "compound assignment operator test 7" )
return 1
lomarf = 0xdeadbeef
lomarf |= 0xabadfeed
if !check( lomarf == 0xffadfeef, "compound assignment operator test 8" )
return 1
lomarf = 0xdeadbeef
lomarf <<= 4
if !check( lomarf == 0xdeadbeef0, "compound assignment operator test 9" )
return 1
lomarf >>= 8
if !check( lomarf == 0xdeadbee, "compound assignment operator test 10" )
return 1
|
Changes to tests/noprelude/execute/higher-func.g.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 |
ct_string someFunc( ct_string $s )
{
return strcat( "someFunc 2: ", $s )
}
if !check( higher( ct_string( ct_string a ){ return strcat( "test1: ", a ) } ) == "test1: higher", "higher order function test 1" )
| | | < < | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
ct_string someFunc( ct_string $s )
{
return strcat( "someFunc 2: ", $s )
}
if !check( higher( ct_string( ct_string a ){ return strcat( "test1: ", a ) } ) == "test1: higher", "higher order function test 1" )
return 1
if !check( higher( ct_string( $t a ){ return strcat( "test2: ", a ) } ) == "test2: higher", "higher order function test 2" )
return 1
if !check( higher( someFunc ) == "someFunc 1: higher", "higher order function test 3" )
return 1
|
Changes to tests/noprelude/execute/higher-poly.g.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 |
ct_string someFunc( ct_string s )
{
return strcat( "someFunc2: ", s )
}
if !check( higherPoly( someFunc ) == "someFunc1: ct_int, someFunc2: blah", "higher order polymorphism test" )
| < < | | 12 13 14 15 16 17 18 19 |
ct_string someFunc( ct_string s )
{
return strcat( "someFunc2: ", s )
}
if !check( higherPoly( someFunc ) == "someFunc1: ct_int, someFunc2: blah", "higher order polymorphism test" )
return 1
|
Changes to tests/noprelude/execute/higher-template.g.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 |
ct_string someFunc( ct_string s )
{
return strcat( "someFunc2: ", s )
}
if !check( higherTpl( ct_string( ct_int a ){ return "test1" }, 123 ) == "higher: test1", "higher order template test 1" )
| | < < | | 12 13 14 15 16 17 18 19 20 21 22 |
ct_string someFunc( ct_string s )
{
return strcat( "someFunc2: ", s )
}
if !check( higherTpl( ct_string( ct_int a ){ return "test1" }, 123 ) == "higher: test1", "higher order template test 1" )
return 1
if !check( higherTpl( someFunc, "meh" ) == "higher: someFunc2: meh", "higher order template test 2" )
return 1
|
Changes to tests/noprelude/execute/if.g.
| ︙ | ︙ | |||
9 10 11 12 13 14 15 |
ct_string func2( bool b )
{
if b return "lomarf"
else return "meh"
}
if !check( func1( true ) == "lomarf", "if test 1" )
| | | | < < | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
ct_string func2( bool b )
{
if b return "lomarf"
else return "meh"
}
if !check( func1( true ) == "lomarf", "if test 1" )
return 1
if !check( func1( false ) == "meh", "if test 2" )
return 1
if !check( func2( true ) == "lomarf", "if test 3" )
return 1
if !check( func2( false ) == "meh", "if test 4" )
return 1
|
Changes to tests/noprelude/execute/locvar.g.
1 2 3 4 5 | #Include( "tests/noprelude/helpers.g" ) uint(32) lomarf = 219 if !check( lomarf == 219, "local variable test 1" ) | | | | | | | | | | | < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#Include( "tests/noprelude/helpers.g" )
uint(32) lomarf = 219
if !check( lomarf == 219, "local variable test 1" )
return 1
if !check( lomarf != 1337, "local variable test 2" )
return 1
lomarf = 1337
if !check( lomarf == 1337, "local variable test 3" )
return 1
uint(32) laffo
if !check( laffo == 0, "local variable test 4" )
return 1
laffo = 219
if !check( laffo == 219, "local variable test 5" )
return 1
// Type inference with a template expression, captures the type in $T as well
$T meh = 12354
if !check( typeName( $T ) == "ct_int", "local variable test 6" )
return 1
if !check( meh == 12354, "local variable test 7" )
return 1
meh = 1337
if !check( meh == 1337, "local variable test 8" )
return 1
// Simple type inference. (really the same as above except we use "var", which is
// an alias for $_, so we use an anonymous tvar and don't capture the type.)
var blah = 8787
if !check( blah == 8787, "local variable test 9" )
return 1
blah = 98997
if !check( blah == 98997, "local variable test 10" )
return 1
// Chained assignment
meh = blah = 1234
if !check( meh == 1234 & blah == 1234, "local variable test 11" )
return 1
|
Changes to tests/noprelude/execute/logicops.g.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 |
bool xor( bool a, bool b )
{
return a ^ b;
}
if !check( lomarf( false, false ) == false, "logic or test 1" )
| | | | | | | | | | | | < < | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
bool xor( bool a, bool b )
{
return a ^ b;
}
if !check( lomarf( false, false ) == false, "logic or test 1" )
return 1
if !check( lomarf( false, true ) == true, "logic or test 2" )
return 1
if !check( lomarf( true, false ) == true, "logic or test 3" )
return 1
if !check( lomarf( true, true ) == true, "logic or test 4" )
return 1
if !check( blah( false, false ) == false, "logic and test 1" )
return 1
if !check( blah( false, true ) == false, "logic and test 2" )
return 1
if !check( blah( true, false ) == false, "logic and test 3" )
return 1
if !check( blah( true, true ) == true, "logic and test 4" )
return 1
if !check( xor( false, false ) == false, "logic xor test 1" )
return 1
if !check( xor( false, true ) == true, "logic xor test 2" )
return 1
if !check( xor( true, false ) == true, "logic xor test 3" )
return 1
if !check( xor( true, true ) == false, "logic xor test 4" )
return 1
|
Changes to tests/noprelude/execute/overloading.g.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 |
ct_string overloadedFunc( ct_string foo, ct_int bar )
{
return "overload 5"
}
if !check( overloadedFunc() == "overload 1", "overload test 1" )
| | | | | < < | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
ct_string overloadedFunc( ct_string foo, ct_int bar )
{
return "overload 5"
}
if !check( overloadedFunc() == "overload 1", "overload test 1" )
return 1
if !check( overloadedFunc( "gg" ) == "overload 2", "overload test 2" )
return 1
if !check( overloadedFunc( 123 ) == "overload 3", "overload test 3" )
return 1
if !check( overloadedFunc( 456, "meh" ) == "overload 4", "overload test 4" )
return 1
if !check( overloadedFunc( "aha", 777 ) == "overload 5", "overload test 5" )
return 1
|
Changes to tests/noprelude/execute/templates.g.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 |
ct_string tplTest2( ct_int foo )
{
return "integer"
}
if !check( tplTest1( 1, 2 ) == "same types", "template test 1" )
| | | | | | | < < | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
ct_string tplTest2( ct_int foo )
{
return "integer"
}
if !check( tplTest1( 1, 2 ) == "same types", "template test 1" )
return 1
if !check( tplTest1( "a", "b" ) == "same types", "template test 2" )
return 1
if !check( tplTest1( 1, "a" ) == "different types", "template test 3" )
return 1
if !check( tplTest1( "b", 45 ) == "different types", "template test 4" )
return 1
if !check( tplTest2( 123 ) == "integer", "template test 5" )
return 1
if !check( tplTest2( "blah" ) == "blah", "template test 6" )
return 1
if !check( tplTest2( Print ) == "whatever", "template test 7" )
return 1
|
Changes to tests/noprelude/execute/tuple.g.
1 2 3 4 5 6 7 8 9 10 11 12 |
#Include( "tests/noprelude/helpers.g" )
// Multiple return values
bool, ct_string foo()
{
return true, "lomarf"
}
// Tuple decomposition using type inferred variable declarations
var a, var b = foo()
if !check( a & b == "lomarf", "tuple test 1" )
| | | | | | < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#Include( "tests/noprelude/helpers.g" )
// Multiple return values
bool, ct_string foo()
{
return true, "lomarf"
}
// Tuple decomposition using type inferred variable declarations
var a, var b = foo()
if !check( a & b == "lomarf", "tuple test 1" )
return 1
// Splicing
ct_int, bool, ct_string, ct_string bar()
{
return 219, foo(), "laffo"
}
var c, var d, var e, var f = bar()
if !check( c == 219 & d & e == "lomarf" & f == "laffo", "tuple test 2" )
return 1
// Swapping variables
e,f = f,e
if !check( e == "laffo" & f == "lomarf", "tuple test 3" )
return 1
// Reading individual tuple members
if !check( bar().0 == 219 & bar().1 & bar().2 == "lomarf" & bar().3 == "laffo", "tuple test 4" )
return 1
var tup = bar()
if !check( tup.0 == 219 & tup.1 & tup.2 == "lomarf" & tup.3 == "laffo", "tuple test 5" )
return 1
// Modifying individual tuple members
tup.2 = "blah"
if !check( tup.0 == 219 & tup.1 & tup.2 == "blah" & tup.3 == "laffo", "tuple test 6" )
return 1
|
Changes to tests/noprelude/execute/using.g.
1 2 3 4 5 6 | #Include( "tests/noprelude/helpers.g" ) using u1 = u2 using u2 = "test" if !check( u1 == "test", "using test" ) | < < | | 1 2 3 4 5 6 7 |
#Include( "tests/noprelude/helpers.g" )
using u1 = u2
using u2 = "test"
if !check( u1 == "test", "using test" )
return 1
|
Changes to tests/noprelude/execute/while.g.
1 2 3 4 5 6 7 8 9 |
#Include( "tests/noprelude/helpers.g" )
var i = 0
while( i < 10 )
{
i += 1
}
if !check( i == 10, "while test" )
| < < | | 1 2 3 4 5 6 7 8 9 10 |
#Include( "tests/noprelude/helpers.g" )
var i = 0
while( i < 10 )
{
i += 1
}
if !check( i == 10, "while test" )
return 1
|
Changes to tests/noprelude/helpers.g.
1 2 3 4 5 |
// Helpers for core language tests, for which we don't want to use
// the prelude and the standard library.
bool check( bool cond, ct_string message )
{
| | | 1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Helpers for core language tests, for which we don't want to use
// the prelude and the standard library.
bool check( bool cond, ct_string message )
{
if !cond Print( strcat( strcat( "check failed: ", message ), "\n" ) )
return cond
}
// An using statement to check diagnostics context that span multiple files.
using Laffo = SomeOtherThing
// Simple function to retrieve a builtin type name
|
| ︙ | ︙ |
Changes to tests/noprelude/meson.build.
1 2 3 4 5 6 7 |
file = configure_file( copy: true,
input: 'helpers.g', output: 'helpers.g'
)
subdir( 'diagnostics' )
subdir( 'execute' )
subdir( 'codegen' )
| | | 1 2 3 4 5 6 7 8 9 |
file = configure_file( copy: true,
input: 'helpers.g', output: 'helpers.g'
)
subdir( 'diagnostics' )
subdir( 'execute' )
subdir( 'codegen' )
subdir( 'combined' )
subdir( 'verify' )
|