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: |
3d8b581261aa99e94896961cd2ce5458 |
| User & Date: | achavasse 2019-08-15 22:37:33.645 |
Context
|
2019-08-15
| ||
| 22:58 | Implemented InitializeLocalVar() for the bool, ct_int and ct_string types. check-in: 6d69e387ac user: achavasse tags: trunk | |
| 22:37 |
| |
| 01:54 | Fixed a couple of typos. check-in: 1e6e7c928d user: achavasse tags: trunk | |
Changes
Changes to bs/builtins/extpoints.cpp.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 |
return;
auto& p = *Parser::GetCurrentParser();
auto bb = p.currentBB();
bb->emplace_back( move( *v.llr() ) );
} );
| < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
return;
auto& p = *Parser::GetCurrentParser();
auto bb = p.currentBB();
bb->emplace_back( move( *v.llr() ) );
} );
using AnyLocVarType = CustomPattern< LocalVar, LocalVar::PatternTypeT >;
RegisterBuiltinFunc< Intrinsic< void ( AnyLocVarType ) > >( e, e.extDropValue(),
[]( const Value& v )
{
return;
} );
using AnyDeclType = CustomPattern< Decl, Decl::PatternTypeT >;
// DropValue for Decls: declare a local variable with default initialization.
// TODO: if the invocation to InitializeValue fails, we should have a way to
// replace the generic "function arguments mismatch" error message with something
// more specific: "can't default-initialize a variable of type XXX"
RegisterBuiltinFunc< Intrinsic< void ( AnyDeclType ) > >( e, e.extDropValue(),
[]( const Value& v )
{
auto& p = *Parser::GetCurrentParser();
if( !p.cfg() )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( 0, "variable declarations are not allowed here." );
return PoisonValue();
}
auto decl = *FromValue< Decl >( v );
return DeclareLocalVar( p, decl.type(), decl.name(), nullopt );
} );
using IntegerLocVarType =
CustomPattern< LocalVar, LocalVar::Pattern< IntegerType::Pattern > >;
using IntegerType = CustomPattern< IntegerType, IntegerType::Pattern >;
RegisterBuiltinFunc< Intrinsic< Value ( IntegerLocVarType, IntegerType ) > >( e, e.extInitializeLocalVar(),
[]( const Value& lv, const Value& initVal )
{
auto locVar = *FromValue< LocalVar >( lv );
return BuildComputedValue( GetValueType< void >(),
SetVar( initVal, locVar.cfgId(), locVar.index() ) );
} );
// Default initialization for integer vars
RegisterBuiltinFunc< Intrinsic< Value ( IntegerLocVarType ) > >( e, e.extInitializeLocalVar(),
[]( const Value& lv )
{
auto locVar = *FromValue< LocalVar >( lv );
auto opTypeVal = *ValueFromIRExpr( locVar.type() );
auto opType = *FromValue< IntegerType >( opTypeVal );
auto initVal = BuildComputedValue( locVar.type(),
LoadConstInt( static_cast< llvm::IntegerType* >( GetLLVMType( opTypeVal ) ),
APSInt( opType.m_numBits, !opType.m_signed ) ) );
return BuildComputedValue( GetValueType< void >(),
SetVar( move( initVal ), locVar.cfgId(), locVar.index() ) );
} );
}
}
|
Changes to bs/builtins/operators/assignment.cpp.
| ︙ | ︙ | |||
28 29 30 31 32 33 34 |
RightAssInfixOp( "operator_assign"_sid, precedence::AssignmentOp,
// Assignment with a decl of type $T to the left and a value of type $T to the right:
// Local variable declaration and initialization.
ForTypes< CustomPattern< Decl, Decl::PatternTypeT >,
CustomPattern< Value, ValuePatternT > >(
[]( auto&& lhs, auto&& rhs ) -> Value
{
| < < < | < | < | < | < < < | < < < < < < | < | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
RightAssInfixOp( "operator_assign"_sid, precedence::AssignmentOp,
// Assignment with a decl of type $T to the left and a value of type $T to the right:
// Local variable declaration and initialization.
ForTypes< CustomPattern< Decl, Decl::PatternTypeT >,
CustomPattern< Value, ValuePatternT > >(
[]( auto&& lhs, auto&& rhs ) -> Value
{
auto& p = *Parser::GetCurrentParser();
if( !p.cfg() )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( 0, "variable declarations are not allowed here." );
return PoisonValue();
}
auto decl = *FromValue< Decl >( lhs );
return DeclareLocalVar( p, decl.type(), decl.name(), rhs );
} ),
// Assignation of a local var.
// We define overloads for every runtime builtin types and directly perform the assignation.
// TODO: we also need a generic overload that invokes an assignation extension point,
// for custom types to implement their own. But we need to implement mutable references
// first.
|
| ︙ | ︙ |
Changes to bs/builtins/statements/hif.cpp.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 |
{
void SetupHIfStmt( Env& e )
{
auto handleHIf = []( Parser& p, uint32_t locationId, uint32_t prec )
{
auto& dm = DiagnosticsManager::GetInstance();
| < < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{
void SetupHIfStmt( Env& e )
{
auto handleHIf = []( Parser& p, uint32_t locationId, uint32_t prec )
{
auto& dm = DiagnosticsManager::GetInstance();
auto np = p.makeNestedParser();
if( !np.parseExpression( precedence::IfStmt ) )
{
dm.emitSyntaxErrorMessage( locationId, "expected an expression following the #if statement1.", 0 );
return false;
}
|
| ︙ | ︙ |
Changes to bs/builtins/statements/if.cpp.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
namespace empathy::builtins
{
void SetupIfStmt( Env& e )
{
auto handleIf = []( Parser& p, uint32_t locationId, uint32_t prec )
{
auto& dm = DiagnosticsManager::GetInstance();
auto pPrecBB = p.currentBB();
auto np = p.makeNestedParser();
if( !np.parseExpression( precedence::IfStmt ) )
{
dm.emitSyntaxErrorMessage( locationId, "expected an expression following the if statement.", 0 );
| > > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
namespace empathy::builtins
{
void SetupIfStmt( Env& e )
{
auto handleIf = []( Parser& p, uint32_t locationId, uint32_t prec )
{
auto& dm = DiagnosticsManager::GetInstance();
if( p.isInParenExpr() )
{
dm.emitSyntaxErrorMessage( locationId, "the if statement is not allowed here.", 0 );
return false;
}
auto pPrecBB = p.currentBB();
auto np = p.makeNestedParser();
if( !np.parseExpression( precedence::IfStmt ) )
{
dm.emitSyntaxErrorMessage( locationId, "expected an expression following the if statement.", 0 );
|
| ︙ | ︙ |
Changes to bs/builtins/statements/return.cpp.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 |
{
void SetupReturnStmt( Env& e )
{
auto handleReturn = []( Parser& p, uint32_t locationId, uint32_t prec )
{
auto& dm = DiagnosticsManager::GetInstance();
| < | < < < > > | | 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 |
{
void SetupReturnStmt( Env& e )
{
auto handleReturn = []( Parser& p, uint32_t locationId, uint32_t prec )
{
auto& dm = DiagnosticsManager::GetInstance();
if( p.isInParenExpr() )
{
dm.emitSyntaxErrorMessage( locationId, "the return statement is not allowed here.", 0 );
return false;
}
const auto& context = p.resolver()->context();
if( context.returnType() == GetValueType< void >() )
{
p.emitTerminator( llr::Ret() );
return true;
}
auto np = p.makeNestedParser();
if( !np.parseExpression( precedence::ReturnStmt + 1 ) )
{
dm.emitSyntaxErrorMessage( locationId, "expected an expression following the return statement.", 0 );
p.emitTerminator( llr::Ret( PoisonValue() ) );
return false;
}
auto retVal = np.popValue();
if( !retVal )
{
dm.emitSyntaxErrorMessage( locationId, "expected an expression following the return statement.", 0 );
p.emitTerminator( llr::Ret( PoisonValue() ) );
return false;
}
|
| ︙ | ︙ |
Changes to bs/builtins/statements/using.cpp.
| ︙ | ︙ | |||
123 124 125 126 127 128 129 |
dm.emitErrorMessage( loc, "invalid expression." );
content = ValueToIRExpr( PoisonValue() );
result = get< Term >( content );
bInUse = false;
return Env::Status::Success;
}
| | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
dm.emitErrorMessage( loc, "invalid expression." );
content = ValueToIRExpr( PoisonValue() );
result = get< Term >( content );
bInUse = false;
return Env::Status::Success;
}
auto result = p.popValue();
if( !result )
{
dm.emitErrorMessage( loc, "invalid expression." );
result = PoisonValue();
}
if( !result->isConstant() )
|
| ︙ | ︙ |
Changes to bs/builtins/types/localvar/localvar.cpp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include "builtins/builtins.h"
using namespace empathy::builtins;
namespace empathy::builtins
{
const Term& LocalVar::PatternTypeT::GetPattern()
{
static auto pattern = GetValueType< LocalVar >( MkHole( "T"_sid ) );
return pattern;
}
}
namespace empathy::ir
{
const Term& Bridge< LocalVarType >::Type()
{
return TypeType();
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
#include "builtins/builtins.h"
#include "parse/parse.h"
using namespace empathy::builtins;
using namespace empathy::llr;
using namespace empathy::parse;
namespace empathy::builtins
{
const Term& LocalVar::PatternTypeT::GetPattern()
{
static auto pattern = GetValueType< LocalVar >( MkHole( "T"_sid ) );
return pattern;
}
Value DeclareLocalVar( Parser& p, const Term& type, StringId name, const optional< Value >& initializer )
{
auto cfgId = p.cfg()->uniqueId();
auto index = p.cfg()->getNewTemporaryIndex();
LocalVar lv( type, cfgId, index );
auto bb = p.currentBB();
bb->emplace_back( AllocVar( *ValueFromIRExpr( type ), cfgId, index ) );
if( initializer )
{
p.pushValue( InvokeOverloadSet( p.resolver()->context(),
p.resolver()->context().env()->extInitializeLocalVar(),
MakeTuple( ToValue( lv ), *initializer ) ) );
}
else
{
p.pushValue( InvokeOverloadSet( p.resolver()->context(),
p.resolver()->context().env()->extInitializeLocalVar(),
MakeTuple( ToValue( lv ) ) ) );
}
auto locVar = ToValue( lv );
auto identity = AppendToVectorTerm( p.resolver()->context().identity(), name );
p.resolver()->context().env()->storeValue( identity, ANYTERM( _ ),
ValueToIRExpr( locVar ) );
p.resolver()->clearLookAheadCache();
return locVar;
}
}
namespace empathy::ir
{
const Term& Bridge< LocalVarType >::Type()
{
return TypeType();
|
| ︙ | ︙ |
Changes to bs/builtins/types/localvar/localvar.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#ifndef EMPATHY_BUILTINS_TYPES_LOCALVAR_H
#define EMPATHY_BUILTINS_TYPES_LOCALVAR_H
namespace empathy::builtins
{
void SetupLocalVarUnification( Env& e );
class LocalVarType
{
public:
template< typename T >
LocalVarType( T&& type ) :
m_type( forward< T >( type ) )
| > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#ifndef EMPATHY_BUILTINS_TYPES_LOCALVAR_H
#define EMPATHY_BUILTINS_TYPES_LOCALVAR_H
namespace empathy::parse
{
class Parser;
}
namespace empathy::builtins
{
void SetupLocalVarUnification( Env& e );
Value DeclareLocalVar( parse::Parser& p, const Term& type, StringId name, const optional< Value >& initializer );
class LocalVarType
{
public:
template< typename T >
LocalVarType( T&& type ) :
m_type( forward< T >( type ) )
|
| ︙ | ︙ |
Changes to bs/codegen/func.cpp.
| ︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 |
Infos inf( c );
// Generate allocas and stores for the args
auto pEntryBB = func.llr()->body()->entryBB();
if( !pEntryBB->llvmBB() )
pEntryBB->setLLVMBB( llvm::BasicBlock::Create( GetLLVMContext(), "", pllvmFunc ) );
m_llvmBuilder.SetInsertPoint( pEntryBB->llvmBB() );
llvm::SmallVector< NullInit< llvm::Value* >, 8 > args;
for( auto&& arg : pllvmFunc->args() )
| > > | > | < | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
Infos inf( c );
// Generate allocas and stores for the args
auto pEntryBB = func.llr()->body()->entryBB();
if( !pEntryBB->llvmBB() )
pEntryBB->setLLVMBB( llvm::BasicBlock::Create( GetLLVMContext(), "", pllvmFunc ) );
inf.allocaBasicBlock = pEntryBB->llvmBB();
m_llvmBuilder.SetInsertPoint( pEntryBB->llvmBB() );
llvm::SmallVector< NullInit< llvm::Value* >, 8 > args;
for( auto&& arg : pllvmFunc->args() )
{
inf.lastEmittedAlloca = m_llvmBuilder.CreateAlloca( arg.getType() );
args.push_back( inf.lastEmittedAlloca );
}
size_t i = 0;
for( auto&& arg : pllvmFunc->args() )
m_llvmBuilder.CreateStore( &arg, args[i++] );
inf.temporaries->setVec( 0, move( args ) );
|
| ︙ | ︙ |
Changes to bs/codegen/instructions.cpp.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 |
llvm::Value* Module::buildInstruction( Infos& inf, const llr::AllocVar& av )
{
auto type = LowerType( inf.context, av.type() );
if( !type )
return nullptr;
llvm::IRBuilderBase::InsertPointGuard g( m_llvmBuilder );
| | > > > > | | < | < | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
llvm::Value* Module::buildInstruction( Infos& inf, const llr::AllocVar& av )
{
auto type = LowerType( inf.context, av.type() );
if( !type )
return nullptr;
llvm::IRBuilderBase::InsertPointGuard g( m_llvmBuilder );
if( inf.lastEmittedAlloca && inf.lastEmittedAlloca->getNextNode() )
m_llvmBuilder.SetInsertPoint( inf.lastEmittedAlloca->getNextNode() );
else
m_llvmBuilder.SetInsertPoint( inf.allocaBasicBlock, inf.allocaBasicBlock->begin() );
inf.lastEmittedAlloca = m_llvmBuilder.CreateAlloca( GetLLVMType( *type ) );
createTemporary( inf, av.cfgId(), av.index(), inf.lastEmittedAlloca );
return inf.lastEmittedAlloca;
}
llvm::Value* Module::buildInstruction( Infos& inf, const llr::GetVar& gv )
{
return m_llvmBuilder.CreateLoad( *inf.temporaries->get( gv.cfgId(), gv.index() ) );
}
|
| ︙ | ︙ |
Changes to bs/codegen/module.h.
| ︙ | ︙ | |||
30 31 32 33 34 35 36 |
private:
struct Infos
{
Infos( const Context& c ) : context( c ) {}
const Context& context;
llvm::SmallVector< llvm::Value*, 8 > m_locals;
| | > > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
private:
struct Infos
{
Infos( const Context& c ) : context( c ) {}
const Context& context;
llvm::SmallVector< llvm::Value*, 8 > m_locals;
llvm::BasicBlock* allocaBasicBlock = nullptr;
llvm::AllocaInst* lastEmittedAlloca = nullptr;
using storage_type = llr::TempStorage< NullInit< llvm::Value* > >;
ptr< storage_type > temporaries = make_shared< storage_type >();
bool inlining = false;
llvm::Value* inlineResult = nullptr;
};
|
| ︙ | ︙ |
Changes to bs/execute/vm.cpp.
| ︙ | ︙ | |||
165 166 167 168 169 170 171 |
return PoisonValue();
return *pVal;
}
optional< Value > VM::execute( const llr::GetVar& gv )
{
const auto* pVal = m_frame.getTemporary( gv.cfgId(), gv.index() );
| < | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
return PoisonValue();
return *pVal;
}
optional< Value > VM::execute( const llr::GetVar& gv )
{
const auto* pVal = m_frame.getTemporary( gv.cfgId(), gv.index() );
if( !pVal )
return PoisonValue();
auto result = Evaluate( **pVal, *this );
if( !result.isConstant() )
return PoisonValue();
|
| ︙ | ︙ |
Changes to bs/parse/blocks.cpp.
| ︙ | ︙ | |||
112 113 114 115 116 117 118 |
{
// Create a nested verbosity context to restrict the scope of
// error silencing caused by syntax errors to the block.
VerbosityContext vc( Verbosity::Normal );
auto tok = m_resolver->consume();
| | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
{
// Create a nested verbosity context to restrict the scope of
// error silencing caused by syntax errors to the block.
VerbosityContext vc( Verbosity::Normal );
auto tok = m_resolver->consume();
auto p = makeNestedParser( Delimiter::OpenParen );
p.parseExpression();
auto content = p.popValue();
auto next = m_resolver->consume();
if( !next )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage(
resolver()->getCurrentLocation(), "')' expected.", 0 );
return PoisonValue();
|
| ︙ | ︙ | |||
215 216 217 218 219 220 221 |
{
// Create a nested verbosity context to restrict the scope of
// error silencing caused by syntax errors to the block.
VerbosityContext vc( Verbosity::Normal );
m_resolver->consume();
| | < < < < | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
{
// Create a nested verbosity context to restrict the scope of
// error silencing caused by syntax errors to the block.
VerbosityContext vc( Verbosity::Normal );
m_resolver->consume();
auto p = makeNestedParser( Delimiter::OpenBrace );
p.parseSequence();
auto next = m_resolver->consumeUnresolved();
if( !next )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage(
resolver()->getCurrentLocation(), "'}' expected.", 0 );
|
| ︙ | ︙ |
Changes to bs/parse/parser.cpp.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
{
Parser p( m_resolver );
p.m_introDelimiter = m_introDelimiter;
p.setCFG( cfg() );
p.setCurrentBB( currentBB() );
return p;
}
void Parser::parseSequence()
{
while( parseExpression( 0 ) )
m_resolver->consumeNewLines();
flushValue();
}
bool Parser::parseExpression( uint32_t precedence )
{
auto next = m_resolver->lookAhead();
| > > > > > > > > > > > | 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 |
{
Parser p( m_resolver );
p.m_introDelimiter = m_introDelimiter;
p.setCFG( cfg() );
p.setCurrentBB( currentBB() );
return p;
}
Parser Parser::makeNestedParser( Delimiter introDelimiter )
{
Parser p( m_resolver, introDelimiter );
p.setCFG( cfg() );
p.setCurrentBB( currentBB() );
return p;
}
void Parser::parseSequence()
{
while( parseExpression( 0 ) )
{
flushValue();
m_resolver->consumeNewLines();
}
flushValue();
}
bool Parser::parseExpression( uint32_t precedence )
{
auto next = m_resolver->lookAhead();
|
| ︙ | ︙ | |||
53 54 55 56 57 58 59 |
void Parser::flushValue()
{
// Flush the pending value, by invoking the DropValue
// extension point, where an overload will decide
// of the value's fate (or possibly emit an error
// if that value wasn't allowed to be discarded).
| | < | > > > | | > | | | < | 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 |
void Parser::flushValue()
{
// Flush the pending value, by invoking the DropValue
// extension point, where an overload will decide
// of the value's fate (or possibly emit an error
// if that value wasn't allowed to be discarded).
while( m_lastValue )
{
auto val = move( *m_lastValue );
m_lastValue = nullopt;
if( val.isPoison() )
return;
DiagnosticsContext dc( val.locationId(), false );
InvokeOverloadSet( resolver()->context(), resolver()->context().env()->extDropValue(),
MakeTuple( val ) );
}
}
optional< uint32_t > Parser::getPrecedence( const Term& t )
{
return visit( [&]( auto&& content )
{
return getPrecedence( t, content );
|
| ︙ | ︙ |
Changes to bs/parse/parser.h.
| ︙ | ︙ | |||
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 |
{
m_pParentParser = ms_pCurrentParser;
ms_pCurrentParser = this;
}
~Parser()
{
ms_pCurrentParser = m_pParentParser;
}
// Static method to retrieve the current parser.
// This is needed by intrinsic functions, specifically
// those that implements the builtin operators: they can't receive
// the parser as a parameter since they can be overloaded by normal
// functions which can't manipulate compile-time data.
// So they need a static method to retrieve it.
static Parser* GetCurrentParser() { return ms_pCurrentParser; }
// Build a parser for a nested parsing context that needs to share everything
// except the current sequence and value.
Parser makeNestedParser();
const auto& resolver() const { return m_resolver; }
auto& resolver() { return m_resolver; }
void parseSequence();
bool parseExpression( uint32_t precedence = 0 );
void parsePostfixExpression( uint32_t precedence );
| > > | 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 |
{
m_pParentParser = ms_pCurrentParser;
ms_pCurrentParser = this;
}
~Parser()
{
flushValue();
ms_pCurrentParser = m_pParentParser;
}
// Static method to retrieve the current parser.
// This is needed by intrinsic functions, specifically
// those that implements the builtin operators: they can't receive
// the parser as a parameter since they can be overloaded by normal
// functions which can't manipulate compile-time data.
// So they need a static method to retrieve it.
static Parser* GetCurrentParser() { return ms_pCurrentParser; }
// Build a parser for a nested parsing context that needs to share everything
// except the current sequence and value.
Parser makeNestedParser();
Parser makeNestedParser( Delimiter introDelimiter );
const auto& resolver() const { return m_resolver; }
auto& resolver() { return m_resolver; }
void parseSequence();
bool parseExpression( uint32_t precedence = 0 );
void parsePostfixExpression( uint32_t precedence );
|
| ︙ | ︙ |
Changes to bs/parse/rule-helpers.inl.
| ︙ | ︙ | |||
15 16 17 18 19 20 21 |
if( !np.parseExpression( precedence + 1 ) )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
| | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
if( !np.parseExpression( precedence + 1 ) )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
rightVal = np.popValue();
if( !rightVal )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
}
|
| ︙ | ︙ | |||
80 81 82 83 84 85 86 |
if( !np.parseExpression( precedence + 1 ) )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
| | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
if( !np.parseExpression( precedence + 1 ) )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
rightVal = np.popValue();
if( !rightVal )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
}
|
| ︙ | ︙ | |||
126 127 128 129 130 131 132 |
if( !np.parseExpression( precedence ) )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
| | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
if( !np.parseExpression( precedence ) )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
rightVal = np.popValue();
if( !rightVal )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
return false;
}
}
|
| ︙ | ︙ |
Changes to tests/noprelude/codegen/locvar.em.
1 2 | using module = CGModuleCreate( "local var test" ) | | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
using module = CGModuleCreate( "local var test" )
using entryPoint = uint(32) ( bool b ) {
uint(32) lomarf = 219
lomarf = 1337
uint(32) laffo
laffo = 654654
return lomarf
}
CGGenerateFunction( module, entryPoint, "main" )
CGModuleEmitLLVMIr( module, "tests/noprelude/codegen/locvar.ll" )
|
Changes to tests/noprelude/codegen/locvar.ll.
1 2 3 | ; ModuleID = 'local var test' source_filename = "local var test" | | > | > > | | > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
; ModuleID = 'local var test'
source_filename = "local var test"
define i32 @main(i1 %0) {
%2 = alloca i1
%3 = alloca i32
%4 = alloca i32
store i1 %0, i1* %2
store i32 219, i32* %3
store i32 1337, i32* %3
store i32 0, i32* %4
store i32 654654, i32* %4
%5 = load i32, i32* %3
ret i32 %5
}
|
Changes to tests/noprelude/diagnostics/template-type-mismatch.em.
1 2 | ExecuteFile( "tests/noprelude/helpers.em" ) | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
ExecuteFile( "tests/noprelude/helpers.em" )
ct_string higherPoly( ct_string( $T s ) $f )
{
return strcat( strcat( $f(5), ", " ), $f( "blah" ) )
}
ct_string someFunc( $T x )
{
return strcat( 219, typeName( $T ) )
}
ct_string someFunc( ct_string s )
{
return strcat( "someFunc2: ", s )
}
if !assert( higherPoly( someFunc ) == "someFunc1: int, someFunc2: blah", "higher order polymorphism test" )
return 0
return 1
|
Changes to tests/noprelude/diagnostics/template-type-mismatch.txt.
|
| | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
tests/noprelude/diagnostics/template-type-mismatch.em:10:12: error: function arguments mismatch.
10 | return strcat( 219, typeName( $T ) )
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
8 | ct_string someFunc( $T x )
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
| In the template function declared here.
...
5 | return strcat( strcat( $f(5), ", " ), $f( "blah" ) )
| ~~~~~
| Called here.
...
3 | ct_string higherPoly( ct_string( $T s ) $f )
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| In the template function declared here.
...
18 | if !assert( higherPoly( someFunc ) == "someFunc1: int, someFunc2: blah", "higher order polymorphism test" )
| ~~~~~~~~~~~~~~~~~~~~~~
| Called here.
|
Changes to tests/noprelude/execute/locvar.em.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 |
if !assert( lomarf != 1337, "local variable test 2" )
return 0
lomarf = 1337
if !assert( lomarf == 1337, "local variable test 3" )
return 0
return 1
| > > > > > > > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
if !assert( lomarf != 1337, "local variable test 2" )
return 0
lomarf = 1337
if !assert( lomarf == 1337, "local variable test 3" )
return 0
uint(32) laffo
if !assert( laffo == 0, "local variable test 4" )
return 0
laffo = 219
if !assert( laffo == 219, "local variable test 5" )
return 0
return 1
|