Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/daScript/ast/ast_expressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -1003,13 +1003,16 @@ namespace das
ExprAssume() { __rtti = "ExprAssume"; };
ExprAssume(const LineInfo & a, const string & al, const ExpressionPtr & se )
: Expression(a), alias(al), subexpr(se) { __rtti = "ExprAssume"; }
ExprAssume(const LineInfo & a, const string & al, const TypeDeclPtr & at )
: Expression(a), alias(al), assumeType(at) { __rtti = "ExprAssume"; }
virtual ExpressionPtr clone( const ExpressionPtr & expr = nullptr ) const override;
virtual SimNode * simulate (Context & context) const override;
virtual ExpressionPtr visit(Visitor & vis) override;
virtual bool rtti_isAssume() const override { return true; }
virtual void serialize( AstSerializer & ser ) override;
string alias;
ExpressionPtr subexpr;
TypeDeclPtr assumeType;
};

template <typename TT>
Expand Down
1 change: 1 addition & 0 deletions include/daScript/ast/ast_typedecl.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ namespace das {
static void clone ( TypeDeclPtr & dest, const TypeDeclPtr & src );
Type getR2VType() const;
int maxBitfieldBits() const;
LineInfo getDeclarationLocation() const;
public:
Type baseType = Type::tVoid;
Structure * structType = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion modules/dasLLVM
7 changes: 5 additions & 2 deletions src/ast/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2326,7 +2326,9 @@ namespace das {
ExpressionPtr ExprAssume::visit(Visitor & vis) {
vis.preVisit(this);
if ( vis.canVisitWithAliasSubexpression(this) ) {
subexpr = subexpr->visit(vis);
if ( subexpr ) subexpr = subexpr->visit(vis);
if ( assumeType ) assumeType = assumeType->visit(vis);

}
return vis.visit(this);
}
Expand All @@ -2335,7 +2337,8 @@ namespace das {
auto cexpr = clonePtr<ExprAssume>(expr);
Expression::clone(cexpr);
cexpr->alias = alias;
cexpr->subexpr = subexpr->clone();
if ( subexpr ) cexpr->subexpr = subexpr->clone();
if ( assumeType ) cexpr->assumeType = make_smart<TypeDecl>(*assumeType);
return cexpr;
}

Expand Down
125 changes: 80 additions & 45 deletions src/ast/ast_infer_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ namespace das {
vector<ExprBlock *> scopes;
vector<ExprWith *> with;
vector<smart_ptr<ExprAssume>> assume;
vector<smart_ptr<ExprAssume>> assumeType;
vector<size_t> varStack;
vector<size_t> assumeStack;
vector<size_t> assumeTypeStack;
vector<bool> inFinally;
bool canFoldResult = true;
das_hash_set<int32_t> labels;
Expand Down Expand Up @@ -131,10 +133,13 @@ namespace das {
void pushVarStack() {
varStack.push_back(local.size());
assumeStack.push_back(assume.size());
assumeTypeStack.push_back(assumeType.size());
}
void popVarStack() {
assume.resize(assumeStack.back());
assumeStack.pop_back();
assumeType.resize(assumeTypeStack.back());
assumeTypeStack.pop_back();
local.resize(varStack.back());
varStack.pop_back();
}
Expand Down Expand Up @@ -377,6 +382,11 @@ namespace das {
// within current context
TypeDeclPtr findAlias ( const string & name ) const {
if ( func ) {
for ( auto & ast : assumeType ) {
if ( ast->alias == name ) {
return ast->assumeType;
}
}
for ( auto it = local.rbegin(), its=local.rend(); it!=its; ++it ) {
auto & var = *it;
if ( auto vT = var->type->findAlias(name) ) {
Expand Down Expand Up @@ -7463,63 +7473,88 @@ namespace das {
Visitor::preVisit(expr);
const auto & name = expr->alias;
// assume
for ( const auto & aa : assume ) {
if ( aa->alias==name ) {
error("can't assume " + name + ", alias already taken by another assume expression at " + aa->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
return;
}
}
// local variable
for ( const auto & lv : local ) {
if ( lv->name==name || lv->aka==name ) {
error("can't assume " + name + ", alias already taken by local variable at " + lv->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
return;
}
}
// with
if ( auto mW = hasMatchingWith(name) ) {
error("can't assume " + name + ", alias already taken by `with` at " + mW->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
return;
}
// block arguments
for ( const auto & block : blocks ) {
for ( const auto & arg : block->arguments ) {
if ( arg->name==name || arg->aka==name ) {
error("can't assume " + name + ", alias already taken by block argument at " + arg->at.describe(), "", "",
if ( expr->subexpr ) {
for ( const auto & aa : assume ) {
if ( aa->alias==name ) {
error("can't assume " + name + ", alias already taken by another assume expression at " + aa->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
return;
}
}
}
// function argument
if ( func ) {
for ( auto & arg : func->arguments ) {
if ( arg->name==name || arg->aka==name ) {
error("can't assume " + name + ", alias already taken by block argument at " + arg->at.describe(), "", "",
// local variable
for ( const auto & lv : local ) {
if ( lv->name==name || lv->aka==name ) {
error("can't assume " + name + ", alias already taken by local variable at " + lv->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
return;
}
}
}
// global
auto globals = findMatchingVar(name, false);
if ( globals.size() ) {
if ( globals.size()==1 ) {
error("can't assume " + name + ", alias already taken by global variable at " + globals[0]->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
} else {
error("can't assume " + name + ", alias already taken by multiple global variables", "", "",
expr->at, CompilationError::invalid_assume);
// with
if ( auto mW = hasMatchingWith(name) ) {
error("can't assume " + name + ", alias already taken by `with` at " + mW->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
return;
}
// block arguments
for ( const auto & block : blocks ) {
for ( const auto & arg : block->arguments ) {
if ( arg->name==name || arg->aka==name ) {
error("can't assume " + name + ", alias already taken by block argument at " + arg->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
return;
}
}
}
// function argument
if ( func ) {
for ( auto & arg : func->arguments ) {
if ( arg->name==name || arg->aka==name ) {
error("can't assume " + name + ", alias already taken by block argument at " + arg->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
return;
}
}
}
// global
auto globals = findMatchingVar(name, false);
if ( globals.size() ) {
if ( globals.size()==1 ) {
error("can't assume " + name + ", alias already taken by global variable at " + globals[0]->at.describe(), "", "",
expr->at, CompilationError::invalid_assume);
} else {
error("can't assume " + name + ", alias already taken by multiple global variables", "", "",
expr->at, CompilationError::invalid_assume);
}
return;
}
} else {
auto clashAlias = findAlias(name);
if ( clashAlias ) {
string extra;
if ( verbose ) {
auto atClash = clashAlias->getDeclarationLocation();
if ( !atClash.empty() ) {
extra = "previously declarated at " + atClash.describe();
}
}
error("can't assume " + name + ", type or alias name is already used", extra, "",
expr->at, CompilationError::invalid_assume);
return;
}
if ( !expr->assumeType ) {
error("assume without subexpression must have type", "", "",
expr->at, CompilationError::invalid_assume);
return;
}
return;
}
}

virtual ExpressionPtr visit ( ExprAssume * expr ) override {
assume.emplace_back(expr);
if ( expr->subexpr ) {
assume.emplace_back(expr);
} else {
assumeType.emplace_back(expr);
}
return expr;
}
// ExprWith
Expand Down Expand Up @@ -8111,7 +8146,7 @@ namespace das {
// we build var_name._partIndex
auto varName = make_smart<ExprVar>(varAt,name);
auto partExpr = make_smart<ExprField>(varAt,varName,"_" + to_string(partIndex),true);
assume.push_back(make_smart<ExprAssume>(varAt,part,partExpr));
assume.push_back(make_smart<ExprAssume>(varAt,part,ExpressionPtr(partExpr)));
partIndex ++;
}

Expand Down
5 changes: 4 additions & 1 deletion src/ast/ast_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,10 @@ namespace das {
}
virtual void preVisit ( ExprAssume * wh ) override {
Visitor::preVisit(wh);
ss << "assume " << wh->alias << " = ";
ss << "assume ";
if ( wh->assumeType ) ss << "type ";
ss << wh->alias << " = ";
if ( wh->assumeType ) ss << wh->assumeType->describe();
}
// tag
virtual void preVisit ( ExprTag * expr ) override {
Expand Down
18 changes: 18 additions & 0 deletions src/ast/ast_typedecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ namespace das
{
}

LineInfo TypeDecl::getDeclarationLocation() const {
if ( !at.empty() ) return at;
switch ( baseType ) {
case Type::tStructure:
if ( structType ) return structType->at;
break;
case Type::tEnumeration:
case Type::tEnumeration8:
case Type::tEnumeration16:
case Type::tEnumeration64:
if ( enumType ) return enumType->at;
break;
default:
break;
}
return LineInfo();
}

int TypeDecl::maxBitfieldBits() const {
switch ( baseType ) {
case Type::tBitfield: return 32;
Expand Down
4 changes: 2 additions & 2 deletions src/builtin/module_builtin_ast_serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1543,7 +1543,7 @@ namespace das {

void ExprAssume::serialize(AstSerializer& ser) {
Expression::serialize(ser);
ser << alias << subexpr;
ser << alias << subexpr << assumeType;
}

void ExprMakeBlock::serialize(AstSerializer & ser) {
Expand Down Expand Up @@ -2314,7 +2314,7 @@ namespace das {
}

uint32_t AstSerializer::getVersion () {
static constexpr uint32_t currentVersion = 66;
static constexpr uint32_t currentVersion = 67;
return currentVersion;
}

Expand Down
Loading