diff --git a/src/Ast2ArlContext.h b/src/Ast2ArlContext.h index 6d3e6ef..51d8edd 100644 --- a/src/Ast2ArlContext.h +++ b/src/Ast2ArlContext.h @@ -82,6 +82,18 @@ class Ast2ArlContext : public virtual IAst2ArlContext { virtual int32_t findBottomUpScope(ast::ISymbolScope *scope) override; + virtual ast::ISymbolScope *inlineCtxt() const override { + return (m_inline_ctxt_s.size())?m_inline_ctxt_s.back():0; + } + + virtual void pushInlineCtxt(ast::ISymbolScope *s) override { + m_inline_ctxt_s.push_back(s); + } + + virtual void popInlineCtxt() override { + m_inline_ctxt_s.pop_back(); + } + virtual ast::ISymbolScope *typeScope() const override; virtual vsc::dm::IDataType *findType(ast::IScopeChild *t) override; @@ -124,6 +136,7 @@ class Ast2ArlContext : public virtual IAst2ArlContext { std::vector> m_scope_s; std::map m_type_m; std::vector m_type_s_idx_s; + std::vector m_inline_ctxt_s; std::vector m_pyref_s; std::vector m_base_s; diff --git a/src/TaskBuildActivity.cpp b/src/TaskBuildActivity.cpp index 633e3b4..c896344 100644 --- a/src/TaskBuildActivity.cpp +++ b/src/TaskBuildActivity.cpp @@ -21,6 +21,7 @@ #include "dmgr/impl/DebugMacros.h" #include "TaskBuildActivity.h" #include "TaskBuildExpr.h" +#include "TaskBuildConstraint.h" #include "zsp/arl/dm/IDataTypeActivityTraverseType.h" #include "zsp/ast/IActivityDecl.h" #include "zsp/parser/impl/TaskResolveSymbolPathRef.h" @@ -88,6 +89,12 @@ void TaskBuildActivity::visitActivityActionHandleTraversal(ast::IActivityActionH vsc::dm::ITypeConstraint *with_c = 0; DEBUG(" ref=%p with_c=%p", ref, with_c); + if (i->getWith_c()) { + m_ctxt->pushInlineCtxt(0); // TODO: get type of inline context + with_c = TaskBuildConstraint(m_ctxt).build(i->getWith_c()); + m_ctxt->popInlineCtxt(); + } + arl::dm::IDataTypeActivityTraverse *t = m_ctxt->ctxt()->mkDataTypeActivityTraverse(ref, with_c); m_scope_s.back()->addActivity(m_ctxt->ctxt()->mkTypeFieldActivity( @@ -114,6 +121,12 @@ void TaskBuildActivity::visitActivityActionTypeTraversal(ast::IActivityActionTyp } vsc::dm::IDataTypeStruct *dt = dynamic_cast(m_ctxt->getType(t)); + if (i->getWith_c()) { + m_ctxt->pushInlineCtxt(ts); + with_c = TaskBuildConstraint(m_ctxt).build(i->getWith_c()); + m_ctxt->popInlineCtxt(); + } + if (dt) { arl::dm::IDataTypeAction *at = dynamic_cast(dt); if (!at) { diff --git a/src/TaskBuildConstraint.cpp b/src/TaskBuildConstraint.cpp new file mode 100644 index 0000000..63e2d88 --- /dev/null +++ b/src/TaskBuildConstraint.cpp @@ -0,0 +1,133 @@ +/* + * TaskBuildConstraint.cpp + * + * Copyright 2023 Matthew Ballance and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Created on: + * Author: + */ +#include "dmgr/impl/DebugMacros.h" +#include "TaskBuildConstraint.h" +#include "TaskBuildExpr.h" + + +namespace zsp { +namespace fe { +namespace parser { + + +TaskBuildConstraint::TaskBuildConstraint(IAst2ArlContext *ctxt) : m_ctxt(ctxt) { + DEBUG_INIT("zsp::fe::parser::TaskBuildConstraint", ctxt->getDebugMgr()); +} + +TaskBuildConstraint::~TaskBuildConstraint() { + +} + +vsc::dm::ITypeConstraint *TaskBuildConstraint::build(ast::IConstraintStmt *c) { + m_ret = 0; + c->accept(m_this); + return m_ret; +} + +void TaskBuildConstraint::visitConstraintBlock(ast::IConstraintBlock *i) { + DEBUG_ENTER("visitConstraintBlock"); + DEBUG_LEAVE("visitConstraintBlock"); +} + +void TaskBuildConstraint::visitConstraintScope(ast::IConstraintScope *i) { + DEBUG_ENTER("visitConstraintScope"); + vsc::dm::ITypeConstraintScope *scope = m_ctxt->ctxt()->mkTypeConstraintScope(); + for (std::vector::const_iterator + it=i->getConstraints().begin(); + it!=i->getConstraints().end(); it++) { + m_ret = 0; + (*it)->accept(m_this); + if (m_ret) { + scope->addConstraint(m_ret); + } + } + m_ret = scope; + DEBUG_LEAVE("visitConstraintScope"); +} + +void TaskBuildConstraint::visitConstraintStmtDefault(ast::IConstraintStmtDefault *i) { } + +void TaskBuildConstraint::visitConstraintStmtDefaultDisable(ast::IConstraintStmtDefaultDisable *i) { } + +void TaskBuildConstraint::visitConstraintStmtExpr(ast::IConstraintStmtExpr *i) { + DEBUG_ENTER("visitConstraintStmtExpr"); + vsc::dm::ITypeExpr *expr = TaskBuildExpr(m_ctxt).build(i->getExpr()); + vsc::dm::ITypeConstraintExpr *expr_c = m_ctxt->ctxt()->mkTypeConstraintExpr(expr, true); + m_ret = expr_c; + DEBUG_LEAVE("visitConstraintStmtExpr"); +} + +void TaskBuildConstraint::visitConstraintStmtField(ast::IConstraintStmtField *i) { } + +void TaskBuildConstraint::visitConstraintStmtIf(ast::IConstraintStmtIf *i) { + vsc::dm::ITypeExpr *cond = TaskBuildExpr(m_ctxt).build(i->getCond()); + m_ret = 0; + i->getTrue_c()->accept(m_this); + vsc::dm::ITypeConstraint *true_c = m_ret; + vsc::dm::ITypeConstraint *false_c = 0; + + if (i->getFalse_c()) { + m_ret = 0; + i->getFalse_c()->accept(m_this); + false_c = m_ret; + } + + vsc::dm::ITypeConstraintIfElse *c = m_ctxt->ctxt()->mkTypeConstraintIfElse( + cond, + true_c, + false_c); + m_ret = c; +} + +void TaskBuildConstraint::visitConstraintStmtImplication(ast::IConstraintStmtImplication *i) { + m_ret = 0; + if (i->getConstraints().size() > 1) { + vsc::dm::ITypeConstraintScope *cs = m_ctxt->ctxt()->mkTypeConstraintScope(); + for (std::vector::const_iterator + it=i->getConstraints().begin(); + it!=i->getConstraints().end(); it++) { + (*it)->accept(m_this); + if (m_ret) { + cs->addConstraint(m_ret); + } + } + m_ret = cs; + } else { + i->getConstraints().at(0)->accept(m_this); + } + + vsc::dm::ITypeConstraintImplies *imp = m_ctxt->ctxt()->mkTypeConstraintImplies( + TaskBuildExpr(m_ctxt).build(i->getCond()), + m_ret); + m_ret = imp; +} + +void TaskBuildConstraint::visitConstraintStmtForeach(ast::IConstraintStmtForeach *i) { } + +void TaskBuildConstraint::visitConstraintStmtForall(ast::IConstraintStmtForall *i) { } + +void TaskBuildConstraint::visitConstraintStmtUnique(ast::IConstraintStmtUnique *i) { } + +dmgr::IDebug *TaskBuildConstraint::m_dbg = 0; + +} +} +} diff --git a/src/TaskBuildConstraint.h b/src/TaskBuildConstraint.h new file mode 100644 index 0000000..c7570fd --- /dev/null +++ b/src/TaskBuildConstraint.h @@ -0,0 +1,79 @@ +/** + * TaskBuildConstraint.h + * + * Copyright 2023 Matthew Ballance and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Created on: + * Author: + */ +#pragma once +#include +#include +#include "dmgr/IDebug.h" +#include "vsc/dm/IDataTypeStruct.h" +#include "zsp/fe/parser/IAst2ArlContext.h" +#include "zsp/ast/IConstraintScope.h" +#include "zsp/ast/impl/VisitorBase.h" + +namespace zsp { +namespace fe { +namespace parser { + + + +class TaskBuildConstraint : + public virtual ast::VisitorBase { +public: + TaskBuildConstraint(IAst2ArlContext *ctxt); + + virtual ~TaskBuildConstraint(); + + vsc::dm::ITypeConstraint *build(ast::IConstraintStmt *c); + + virtual void visitConstraintBlock(ast::IConstraintBlock *i) override; + + virtual void visitConstraintScope(ast::IConstraintScope *i) override; + + virtual void visitConstraintStmtDefault(ast::IConstraintStmtDefault *i) override; + + virtual void visitConstraintStmtDefaultDisable(ast::IConstraintStmtDefaultDisable *i) override; + + virtual void visitConstraintStmtExpr(ast::IConstraintStmtExpr *i) override; + + virtual void visitConstraintStmtField(ast::IConstraintStmtField *i) override; + + virtual void visitConstraintStmtIf(ast::IConstraintStmtIf *i) override; + + virtual void visitConstraintStmtImplication(ast::IConstraintStmtImplication *i) override; + + virtual void visitConstraintStmtForeach(ast::IConstraintStmtForeach *i) override; + + virtual void visitConstraintStmtForall(ast::IConstraintStmtForall *i) override; + + virtual void visitConstraintStmtUnique(ast::IConstraintStmtUnique *i) override; + +private: + static dmgr::IDebug *m_dbg; + IAst2ArlContext *m_ctxt; + vsc::dm::ITypeConstraint *m_ret; + std::vector m_scope_s; + +}; + +} +} +} + + diff --git a/src/TaskBuildDataType.cpp b/src/TaskBuildDataType.cpp index 282c67e..0a86247 100644 --- a/src/TaskBuildDataType.cpp +++ b/src/TaskBuildDataType.cpp @@ -274,7 +274,6 @@ void TaskBuildDataType::visitDataTypeString(ast::IDataTypeString *i) { void TaskBuildDataType::visitDataTypeUserDefined(ast::IDataTypeUserDefined *i) { DEBUG_ENTER("visitDataTypeUserDefined"); - i->getType_id()->getElems().size(); for (std::vector::const_iterator it=i->getType_id()->getElems().begin(); it!=i->getType_id()->getElems().end(); it++) { diff --git a/src/TaskBuildExpr.cpp b/src/TaskBuildExpr.cpp index 36f9ded..45a26dd 100644 --- a/src/TaskBuildExpr.cpp +++ b/src/TaskBuildExpr.cpp @@ -350,7 +350,8 @@ void TaskBuildExpr::visitExprRefPathContext(ast::IExprRefPathContext *i) { RootRefT root_ref = mkRootFieldRef(i); zsp::parser::TaskResolveSymbolPathRef resolver( m_ctxt->getDebugMgr(), - m_ctxt->getRoot()); + m_ctxt->getRoot(), + m_ctxt->inlineCtxt()); ast::IScopeChild *ast_scope = resolver.resolve(i->getTarget()); DEBUG("ast_scope: %s", zsp::parser::TaskGetName().get(ast_scope, true).c_str()); @@ -556,6 +557,7 @@ TaskBuildExpr::RootRefT TaskBuildExpr::mkRootFieldRef(ast::IExprRefPathContext * m_ctxt->symScopes().size()); ast::ISymbolScope *scope = m_ctxt->rootSymScopeT(); int32_t type_scope_idx=-1, bup_scope_idx=-1; + ast::ISymbolScope *inline_ctxt = 0; uint32_t ii; if (DEBUG_EN) { for (ii=0; iigetTarget()->getPath().size(); ii++) { @@ -565,10 +567,11 @@ TaskBuildExpr::RootRefT TaskBuildExpr::mkRootFieldRef(ast::IExprRefPathContext * } } for (ii=0; iigetTarget()->getPath().size(); ii++) { - DEBUG("Scope: %s ; ii=%d idx=%d children=%d", + DEBUG("Scope: %s ; ii=%d idx=%d kind=%d children=%d", scope->getName().c_str(), ii, i->getTarget()->getPath().at(ii).idx, + i->getTarget()->getPath().at(ii).kind, scope->getChildren().size()); ast::IScopeChild *c = 0; @@ -580,17 +583,26 @@ TaskBuildExpr::RootRefT TaskBuildExpr::mkRootFieldRef(ast::IExprRefPathContext * c = func->getPlist()->getChildren().at( i->getTarget()->getPath().at(ii).idx).get(); } break; + case ast::SymbolRefPathElemKind::ElemKind_Inline: { + DEBUG("ElemKind_Inline: %p", m_ctxt->inlineCtxt()); + inline_ctxt = m_ctxt->inlineCtxt(); + } break; default: c = scope->getChildren().at( i->getTarget()->getPath().at(ii).idx).get(); break; } - DEBUG("Scope=%s typeScope=%s symScope=%s", + DEBUG("Scope=%s typeScope=%s symScope=%s c=%p inline_ctxt=%p", scope->getName().c_str(), m_ctxt->typeScope()->getName().c_str(), - m_ctxt->symScope()->getName().c_str()); - if (c == m_ctxt->typeScope()) { + m_ctxt->symScope()->getName().c_str(), + c, + inline_ctxt); + if (inline_ctxt) { + DEBUG("Found inline type scope @ %d ", ii); + break; + } else if (c == m_ctxt->typeScope()) { DEBUG("Found type scope @ %d (%s)", ii, m_ctxt->typeScope()->getName().c_str()); // we're looking at the *next* entry, so adjust @@ -610,98 +622,122 @@ TaskBuildExpr::RootRefT TaskBuildExpr::mkRootFieldRef(ast::IExprRefPathContext * } if (ii+1 < i->getTarget()->getPath().size()) { + if (!dynamic_cast(c)) { + DEBUG_ERROR("Failed to convert c to scope"); + } scope = dynamic_cast(c); } } - DEBUG("type_scope_idx=%d bup_scope_idx=%d ii=%d path.size=%d", - type_scope_idx, bup_scope_idx, ii, i->getTarget()->getPath().size()); - - // Determine how to get to the root identifier - // - It's a field within the current action - // - It's a field relative to where we are - // - // Then, determine how to proceed - // - - vsc::dm::ITypeExpr *expr = 0; - if (bup_scope_idx != -1) { - // First, keep going along the path to find the last - // bottom-up scope on the path - for (; iigetTarget()->getPath().size()-1; ii++) { - int32_t t_bup_scope_idx; - ast::IScopeChild *c = scope->getChildren().at( - i->getTarget()->getPath().at(ii).idx).get(); - scope = dynamic_cast(c); - - if ((t_bup_scope_idx=m_ctxt->findBottomUpScope(scope)) != -1) { - DEBUG("Found bottom-up scope %d @ path index %d", t_bup_scope_idx, ii); - bup_scope_idx = t_bup_scope_idx; - } else { - DEBUG("Reached the end of bottom-up scopes @ %d", ii); - break; + if (inline_ctxt) { + field_ref = m_ctxt->ctxt()->mkTypeExprRefInline(); + DEBUG("inline_ctxt: field_ref=%p (ii=%d/%d)", + field_ref, ii, i->getTarget()->getPath().size()); + ii++; + for (; iigetTarget()->getPath().size(); ii++) { + switch (i->getTarget()->getPath().at(ii).kind) { + case ast::SymbolRefPathElemKind::ElemKind_ChildIdx: { + field_ref = m_ctxt->ctxt()->mkTypeExprSubField( + field_ref, + true, + i->getTarget()->getPath().at(ii).idx + ); + } break; + default: + DEBUG_ERROR("Unexpected elem-kind %d", i->getTarget()->getPath().at(ii).kind); + break; } } + } else { + DEBUG("type_scope_idx=%d bup_scope_idx=%d ii=%d path.size=%d", + type_scope_idx, bup_scope_idx, ii, i->getTarget()->getPath().size()); + + // Determine how to get to the root identifier + // - It's a field within the current action + // - It's a field relative to where we are + // + // Then, determine how to proceed + // - + vsc::dm::ITypeExpr *expr = 0; + if (bup_scope_idx != -1) { + // First, keep going along the path to find the last + // bottom-up scope on the path + for (; iigetTarget()->getPath().size()-1; ii++) { + int32_t t_bup_scope_idx; + ast::IScopeChild *c = scope->getChildren().at( + i->getTarget()->getPath().at(ii).idx).get(); + scope = dynamic_cast(c); - DEBUG("Processing bottom-up reference"); + if ((t_bup_scope_idx=m_ctxt->findBottomUpScope(scope)) != -1) { + DEBUG("Found bottom-up scope %d @ path index %d", t_bup_scope_idx, ii); + bup_scope_idx = t_bup_scope_idx; + } else { + DEBUG("Reached the end of bottom-up scopes @ %d", ii); + break; + } + } - if (ii < i->getTarget()->getPath().size()) { - DEBUG("Path elem: %d", i->getTarget()->getPath().at(ii).kind); - switch (i->getTarget()->getPath().at(ii).kind) { - case ast::SymbolRefPathElemKind::ElemKind_ArgIdx: { - // The parameters scope will be above the function scope - DEBUG("Expression reference a parameter ; look one level above"); - bup_scope_idx += 1; - } break; + DEBUG("Processing bottom-up reference"); + + if (ii < i->getTarget()->getPath().size()) { + DEBUG("Path elem: %d", i->getTarget()->getPath().at(ii).kind); + switch (i->getTarget()->getPath().at(ii).kind) { + case ast::SymbolRefPathElemKind::ElemKind_ArgIdx: { + // The parameters scope will be above the function scope + DEBUG("Expression reference a parameter ; look one level above"); + bup_scope_idx += 1; + } break; + } } - } - field_ref = m_ctxt->ctxt()->mkTypeExprRefBottomUp( - bup_scope_idx, - i->getTarget()->getPath().at(ii).idx); - - DEBUG("Bottom-up Ref: scope_offset=%d subfield_idx=%d", - bup_scope_idx, - i->getTarget()->getPath().at(ii).idx); - - ii = 1; - } else if (type_scope_idx != -1) { - DEBUG("type_scope_idx=%d (PathSize-1)=%d", - type_scope_idx, - (i->getTarget()->getPath().size()-1)); -// if (type_scope_idx == (i->getTarget()->getPath().size()-1)) { - // Reference is to a field within the active type - DEBUG("Type-context reference"); - field_ref = m_ctxt->ctxt()->mkTypeExprSubField( - m_ctxt->ctxt()->mkTypeExprRefTopDown(), - true, - i->getTarget()->getPath().back().idx); - ii = 1; + field_ref = m_ctxt->ctxt()->mkTypeExprRefBottomUp( + bup_scope_idx, + i->getTarget()->getPath().at(ii).idx); - // TODO: determine if this is actually a static reference -// } else { -// DEBUG_ERROR("Failed consistency check type_scope_idx=%d path.size=%d", -// type_scope_idx, -// i->getTarget()->getPath().size()); -// } - } else { // Neither top-down nor bottom-up context based - if (i->getHier_id()->getElems().at(0)->getParams()) { - DEBUG("Global function call"); - zsp::parser::TaskResolveSymbolPathRef resolver( - m_ctxt->getDebugMgr(), - m_ctxt->getRoot()); - ast::IScopeChild *ast_scope = resolver.resolve(i->getTarget()); + DEBUG("Bottom-up Ref: scope_offset=%d subfield_idx=%d", + bup_scope_idx, + i->getTarget()->getPath().at(ii).idx); - field_ref = buildRefExpr( - 0, - i, - 0, - ast_scope - ); ii = 1; - } else { - DEBUG_ERROR("Neither bottom-up or top-down"); + } else if (type_scope_idx != -1) { + DEBUG("type_scope_idx=%d (PathSize-1)=%d", + type_scope_idx, + (i->getTarget()->getPath().size()-1)); + // if (type_scope_idx == (i->getTarget()->getPath().size()-1)) { + // Reference is to a field within the active type + DEBUG("Type-context reference"); + field_ref = m_ctxt->ctxt()->mkTypeExprSubField( + m_ctxt->ctxt()->mkTypeExprRefTopDown(), + true, + i->getTarget()->getPath().back().idx); + ii = 1; + + // TODO: determine if this is actually a static reference + // } else { + // DEBUG_ERROR("Failed consistency check type_scope_idx=%d path.size=%d", + // type_scope_idx, + // i->getTarget()->getPath().size()); + // } + } else { // Neither top-down nor bottom-up context based + if (i->getHier_id()->getElems().at(0)->getParams()) { + DEBUG("Global function call"); + zsp::parser::TaskResolveSymbolPathRef resolver( + m_ctxt->getDebugMgr(), + m_ctxt->getRoot()); + ast::IScopeChild *ast_scope = resolver.resolve(i->getTarget()); + + field_ref = buildRefExpr( + 0, + i, + 0, + ast_scope + ); + ii = 1; + } else { + DEBUG_ERROR("Neither bottom-up or top-down"); + } } - } + } // end !inline DEBUG_LEAVE("mkRootFieldRef {%p, %d}", field_ref, ii); return {field_ref, ii}; diff --git a/src/TaskBuildTypeConstraints.h b/src/TaskBuildTypeConstraints.h index 640c961..490a45a 100644 --- a/src/TaskBuildTypeConstraints.h +++ b/src/TaskBuildTypeConstraints.h @@ -45,6 +45,8 @@ class TaskBuildTypeConstraints : public virtual ast::VisitorBase { virtual void visitAction(ast::IAction *i) override; + virtual void visitActivityDecl(ast::IActivityDecl *i) override { } + virtual void visitComponent(ast::IComponent *i) override; virtual void visitStruct(ast::IStruct *i) override; diff --git a/src/include/zsp/fe/parser/IAst2ArlContext.h b/src/include/zsp/fe/parser/IAst2ArlContext.h index ee381b3..202e23c 100644 --- a/src/include/zsp/fe/parser/IAst2ArlContext.h +++ b/src/include/zsp/fe/parser/IAst2ArlContext.h @@ -70,6 +70,12 @@ class IAst2ArlContext { virtual int32_t findBottomUpScope(ast::ISymbolScope *scope) = 0; + virtual ast::ISymbolScope *inlineCtxt() const = 0; + + virtual void pushInlineCtxt(ast::ISymbolScope *s) = 0; + + virtual void popInlineCtxt() = 0; + virtual ast::ISymbolScope *typeScope() const = 0; virtual vsc::dm::IDataType *findType(ast::IScopeChild *t) = 0;