diff --git a/src/dale/CommonDecl/CommonDecl.cpp b/src/dale/CommonDecl/CommonDecl.cpp index 10834c9a..3f0c15a3 100644 --- a/src/dale/CommonDecl/CommonDecl.cpp +++ b/src/dale/CommonDecl/CommonDecl.cpp @@ -40,7 +40,7 @@ bool addVariable(Unit *unit, const char *name, Type *type, var->type = type; var->symbol.append(name); var->linkage = Linkage::Extern; - bool res = ctx->ns()->addVariable(name, var); + bool res = ctx->addVariable(name, var); assert(res); _unused(res); diff --git a/src/dale/Context/Context.cpp b/src/dale/Context/Context.cpp index d87ab2b5..a5bbcac2 100644 --- a/src/dale/Context/Context.cpp +++ b/src/dale/Context/Context.cpp @@ -54,42 +54,6 @@ Context::~Context() { deleteNamespaces(namespaces); } Namespace *Context::ns() { return active_ns_nodes.back()->ns; } -bool Context::popUntilNamespace(Namespace *ns) { - assert(ns && "null argument to popUntilNamespace"); - - for (;;) { - if (active_ns_nodes.size() == 0) { - fprintf(stderr, - "Internal error: no active namespaces left.\n"); - abort(); - } - if (active_ns_nodes.back()->ns == ns) { - break; - } - active_ns_nodes.pop_back(); - } - std::vector new_used_nodes; - for (;;) { - if (used_ns_nodes.size() == 0) { - fprintf(stderr, - "Internal error: no used namespaces left.\n"); - abort(); - } - if (used_ns_nodes.back()->ns == ns) { - break; - } - if (used_ns_nodes.back()->ns->name.compare(0, 4, "anon")) { - new_used_nodes.push_back(used_ns_nodes.back()); - } - used_ns_nodes.pop_back(); - } - std::reverse(new_used_nodes.begin(), new_used_nodes.end()); - std::copy(new_used_nodes.begin(), new_used_nodes.end(), - back_inserter(used_ns_nodes)); - - return true; -} - bool Context::activateNamespace(const char *name) { assert(active_ns_nodes.size() && "no active namespace nodes"); @@ -182,6 +146,22 @@ bool Context::deactivateAnonymousNamespace() { return true; } +void Context::activateFunctionScope(Function *fn) { + active_function_scopes.push_back(fn); +} + +void Context::deactivateFunctionScope(Function *fn) { + assert((active_function_scopes.size() && + active_function_scopes.back() == fn) + && "unmatched function scope"); + active_function_scopes.pop_back(); +} + +Function *Context::getCurrentFunctionScope() { + if (!active_function_scopes.size()) return NULL; + return active_function_scopes.back(); +} + NSNode *getNSNodeFromNode(std::vector *ns_parts, NSNode *current) { for (std::vector::iterator b = ns_parts->begin(), @@ -471,7 +451,12 @@ Function *Context::getFunction(const char *name, return NULL; } -Variable *Context::getVariable(const char *name) { +bool Context::addVariable(const char* name, Variable *var) { + var->fn = getCurrentFunctionScope(); + return ns()->addVariable(name, var); +} + +Variable* Context::getVariableInner(const char *name) { if (strchr(name, '.')) { Namespace *ns = getNamespace(name, true); if (!ns) { @@ -501,6 +486,15 @@ Variable *Context::getVariable(const char *name) { return NULL; } +Variable *Context::getVariable(const char *name) { + Variable *ret = getVariableInner(name); + if (ret && ret->fn && ret->fn != getCurrentFunctionScope()) { + // the variable can't be referenced as a value + return NULL; + } + return ret; +} + Struct *Context::getStruct(const char *name) { if (strchr(name, '.')) { Namespace *ns = getNamespace(name, true); diff --git a/src/dale/Context/Context.h b/src/dale/Context/Context.h index 42a650dc..85c83e67 100644 --- a/src/dale/Context/Context.h +++ b/src/dale/Context/Context.h @@ -50,6 +50,11 @@ class Context { std::vector retrieved_var; /*! Functions that have been retrieved. */ std::vector retrieved_fn; + /*! Active function scopes. It will be an empty vector for global + * variables. */ + std::vector active_function_scopes; + + Variable *getVariableInner(const char *name); public: /*! The native types for the context. Used primarily for type @@ -87,12 +92,6 @@ class Context { /*! Get the currently-active namespace. */ Namespace *ns(); - /*! Pop active namespaces until the given namespace has been - * reached. Does the same thing for used namespaces, save that - * only anonymous namespaces are removed. - * @param ns The namespace that needs to be reached. - */ - bool popUntilNamespace(Namespace *ns); /*! Activate the namespace with the given name. * @param name The name of the namespace. @@ -135,6 +134,24 @@ class Context { */ bool deactivateAnonymousNamespace(); + /*! Activate a function scope. + * + * The function scopes is a set of scopes parallel to namespaces, + * and used to catch invalid variable references to a local + * variable in a different function. + * @param fn The new function scope. + */ + void activateFunctionScope(Function *fn); + /*! Deactivate the current function scope. + * @param fn The function scope to deactivate. + */ + void deactivateFunctionScope(Function *fn); + /*! Get the current active function scope. + * @return Returns NULL, if currently it's outside of any function + * scope (i.e. the function scope of global variables). + */ + Function *getCurrentFunctionScope(); + /*! Retrieve a namespace node by name. * @param name The name of the namespace. * @param ignore_last Whether to ignore the last segment of the @@ -200,10 +217,14 @@ class Context { Function **closest_fn, bool is_macro, std::vector *lvalues = NULL, std::vector *array_types = NULL); + /*! Add a variable to the current active namespace and with the + * current active function scope. */ + bool addVariable(const char *name, Variable *var); /*! Get the variable with the given name. * - * See Namespace::getVariable. As per getFunction, this iterates - * over the used namespaces, calling that method. + * See Namespace::getVariable. As per getFunction, this iterates + * over the used namespaces, calling that method. This also takes + * care of function scopes. */ Variable *getVariable(const char *name); /*! Get the struct with the given name. diff --git a/src/dale/ErrorType/ErrorType.cpp b/src/dale/ErrorType/ErrorType.cpp index 0e14c44a..47d829f4 100644 --- a/src/dale/ErrorType/ErrorType.cpp +++ b/src/dale/ErrorType/ErrorType.cpp @@ -108,7 +108,7 @@ const char *errorInstanceToString(int error_instance) { ret = "not in scope: '%s'"; break; case ErrorInst::VariableNotInScope: - ret = "variable not in scope: '%s'"; + ret = "variable not in scope or cannot be used as value: '%s'"; break; case ErrorInst::UnexpectedElement: ret = "expected %s for %s (got %s instead)"; diff --git a/src/dale/Form/Function/Function.cpp b/src/dale/Form/Function/Function.cpp index 66fb8c8c..a9fe8180 100644 --- a/src/dale/Form/Function/Function.cpp +++ b/src/dale/Form/Function/Function.cpp @@ -189,7 +189,7 @@ Type *parseReturnType(Units *units, Context *ctx, for (std::vector::iterator b = parameters->begin(), e = parameters->end(); b != e; ++b) { - ctx->ns()->addVariable((*b)->name.c_str(), (*b)); + ctx->addVariable((*b)->name.c_str(), (*b)); } Type *ret_type = @@ -473,9 +473,6 @@ bool FormFunctionParse(Units *units, Node *node, const char *name, return true; } - ctx->activateAnonymousNamespace(); - std::string anon_name = ctx->ns()->name; - units->top()->pushGlobalFunction(fn); FormProcBodyParse(units, node, fn, llvm_fn, (next_index + 2), is_anonymous, llvm_return_value); @@ -488,8 +485,6 @@ bool FormFunctionParse(Units *units, Node *node, const char *name, addInitChannelsCall(ctx, llvm_fn); } - ctx->deactivateNamespace(anon_name.c_str()); - if (units->debug) { moduleDebugPass(units->top()->module); } diff --git a/src/dale/Form/Proc/Def/Def.cpp b/src/dale/Form/Proc/Def/Def.cpp index 784effba..644d05e7 100644 --- a/src/dale/Form/Proc/Def/Def.cpp +++ b/src/dale/Form/Proc/Def/Def.cpp @@ -37,22 +37,10 @@ bool typeRequiresExplicitInit(Context *ctx, Type *type) { llvm::Constant *parseGlobalLiteral(Units *units, Type *type, Node *node) { - Context *ctx = units->top()->ctx; - - std::vector active_ns_nodes = ctx->active_ns_nodes; - std::vector used_ns_nodes = ctx->used_ns_nodes; - if (!units->prefunction_ns) { - units->prefunction_ns = ctx->active_ns_nodes.front()->ns; - } - ctx->popUntilNamespace(units->prefunction_ns); - llvm::Constant *init = NULL; int size; init = FormValueParse(units, type, node, &size); - ctx->active_ns_nodes = active_ns_nodes; - ctx->used_ns_nodes = used_ns_nodes; - return init; } @@ -242,7 +230,7 @@ bool parseImplicitVarDefinition(Units *units, Function *fn, llvm::cast(builder.CreateAlloca(llvm_type)); var->value = dst_ptr; - res = ctx->ns()->addVariable(name, var); + res = ctx->addVariable(name, var); if (!res) { Error *e = new Error(RedefinitionOfVariable, node, name); ctx->er->addError(e); @@ -313,7 +301,7 @@ bool parseExplicitVarDefinition(Units *units, Function *fn, var->value = dst_ptr; var->linkage = linkage; - bool res = ctx->ns()->addVariable(name, var); + bool res = ctx->addVariable(name, var); if (!res) { Error *e = new Error(RedefinitionOfVariable, node, name); ctx->er->addError(e); @@ -440,7 +428,7 @@ bool parseExplicitVarDefinition(Units *units, Function *fn, llvm_var->setInitializer(init); - bool res = ctx->ns()->addVariable(name, var); + bool res = ctx->addVariable(name, var); if (!res) { Error *e = new Error(RedefinitionOfVariable, node, name); ctx->er->addError(e); diff --git a/src/dale/Form/Proc/Inst/Inst.cpp b/src/dale/Form/Proc/Inst/Inst.cpp index ded69804..8b94269f 100644 --- a/src/dale/Form/Proc/Inst/Inst.cpp +++ b/src/dale/Form/Proc/Inst/Inst.cpp @@ -31,13 +31,6 @@ bool createAnonymousFunction(Units *units, llvm::BasicBlock *block, Context *ctx = units->top()->ctx; int preindex = ctx->lv_index; - std::vector active_ns_nodes = ctx->active_ns_nodes; - std::vector used_ns_nodes = ctx->used_ns_nodes; - if (!units->prefunction_ns) { - units->prefunction_ns = ctx->active_ns_nodes.front()->ns; - } - ctx->popUntilNamespace(units->prefunction_ns); - int error_count_begin = ctx->er->getErrorTypeCount(ErrorType::Error); @@ -49,8 +42,6 @@ bool createAnonymousFunction(Units *units, llvm::BasicBlock *block, int error_count_end = ctx->er->getErrorTypeCount(ErrorType::Error); if (error_count_begin != error_count_end) { - ctx->active_ns_nodes = active_ns_nodes; - ctx->used_ns_nodes = used_ns_nodes; return false; } @@ -76,9 +67,6 @@ bool createAnonymousFunction(Units *units, llvm::BasicBlock *block, (*b)->index = 0; } - ctx->active_ns_nodes = active_ns_nodes; - ctx->used_ns_nodes = used_ns_nodes; - return true; } diff --git a/src/dale/Form/ProcBody/ProcBody.cpp b/src/dale/Form/ProcBody/ProcBody.cpp index 27d855fc..4302d1e2 100644 --- a/src/dale/Form/ProcBody/ProcBody.cpp +++ b/src/dale/Form/ProcBody/ProcBody.cpp @@ -69,7 +69,7 @@ bool addVariables(Context *ctx, Node *node, Function *fn, } } bool res = - ctx->ns()->addVariable(param_var->name.c_str(), param_var); + ctx->addVariable(param_var->name.c_str(), param_var); if (!res) { Error *e = new Error(RedefinitionOfVariable, node, param_var->name.c_str()); @@ -105,7 +105,7 @@ bool addRetval(Context *ctx, Node *node, Function *fn, var->index = 0; var->linkage = Linkage::Auto; - bool res = ctx->ns()->addVariable(var->name.c_str(), var); + bool res = ctx->addVariable(var->name.c_str(), var); if (!res) { Error *e = new Error(RedefinitionOfVariable, node, var->name.c_str()); @@ -330,9 +330,9 @@ void removePostTerminators(llvm::Function *llvm_fn) { } } -bool FormProcBodyParse(Units *units, Node *node, Function *fn, - llvm::Function *llvm_fn, int skip, - bool is_anonymous, llvm::Value *return_value) { +static bool FormProcBodyParseInner(Units *units, Node *node, Function *fn, + llvm::Function *llvm_fn, int skip, + bool is_anonymous, llvm::Value *return_value) { Context *ctx = units->top()->ctx; std::vector *lst = node->list; @@ -405,4 +405,21 @@ bool FormProcBodyParse(Units *units, Node *node, Function *fn, return true; } + +bool FormProcBodyParse(Units *units, Node *node, Function *fn, + llvm::Function *llvm_fn, int skip, + bool is_anonymous, llvm::Value *return_value) { + Context *ctx = units->top()->ctx; + ctx->activateAnonymousNamespace(); + std::string anon_name = ctx->ns()->name; + ctx->activateFunctionScope(fn); + + bool ret = FormProcBodyParseInner(units, node, fn, llvm_fn, skip, is_anonymous, return_value); + + ctx->deactivateFunctionScope(fn); + ctx->deactivateNamespace(anon_name.c_str()); + + return ret; +} + } diff --git a/src/dale/Form/TopLevel/GlobalVariable/GlobalVariable.cpp b/src/dale/Form/TopLevel/GlobalVariable/GlobalVariable.cpp index d6494475..57ea1b01 100644 --- a/src/dale/Form/TopLevel/GlobalVariable/GlobalVariable.cpp +++ b/src/dale/Form/TopLevel/GlobalVariable/GlobalVariable.cpp @@ -134,7 +134,7 @@ bool FormTopLevelGlobalVariableParse(Units *units, Node *node, var->once_tag = units->top()->once_tag; var->linkage = linkage; - bool res = ctx->ns()->addVariable(name, var); + bool res = ctx->addVariable(name, var); if (!res) { Error *e = new Error(RedefinitionOfVariable, def_node, name); ctx->er->addError(e); diff --git a/src/dale/Form/TopLevel/Macro/Macro.cpp b/src/dale/Form/TopLevel/Macro/Macro.cpp index 3d4c259c..042926ca 100644 --- a/src/dale/Form/TopLevel/Macro/Macro.cpp +++ b/src/dale/Form/TopLevel/Macro/Macro.cpp @@ -221,12 +221,9 @@ bool FormTopLevelMacroParse(Units *units, Node *node, int error_count_begin = ctx->er->getErrorTypeCount(ErrorType::Error); - ctx->activateAnonymousNamespace(); - std::string anon_name = ctx->ns()->name; units->top()->pushGlobalFunction(fn); FormProcBodyParse(units, top, fn, llvm_fn, 3, 0); units->top()->popGlobalFunction(); - ctx->deactivateNamespace(anon_name.c_str()); int error_count_end = ctx->er->getErrorTypeCount(ErrorType::Error); diff --git a/src/dale/Form/Value/Value.cpp b/src/dale/Form/Value/Value.cpp index 000d26d3..691756b1 100644 --- a/src/dale/Form/Value/Value.cpp +++ b/src/dale/Form/Value/Value.cpp @@ -34,23 +34,10 @@ bool parseFunction(Units *units, Type *type, Node *top, Function *fn) { nodes.push_back(top); Node *copy_top = new Node(&nodes); - std::vector active_ns_nodes = ctx->active_ns_nodes; - std::vector used_ns_nodes = ctx->used_ns_nodes; - if (!units->prefunction_ns) { - units->prefunction_ns = ctx->active_ns_nodes.front()->ns; - } - ctx->popUntilNamespace(units->prefunction_ns); - units->top()->pushGlobalFunction(fn); - ctx->activateAnonymousNamespace(); - std::string anon_name = ctx->ns()->name; FormProcBodyParse(units, copy_top, fn, llvm_fn, 0, 0); - ctx->deactivateNamespace(anon_name.c_str()); units->top()->popGlobalFunction(); - ctx->active_ns_nodes = active_ns_nodes; - ctx->used_ns_nodes = used_ns_nodes; - int error_count_end = ctx->er->getErrorTypeCount(ErrorType::Error); if (error_count_begin != error_count_end) { llvm_fn->replaceAllUsesWith( diff --git a/src/dale/Introspection/Introspection.cpp b/src/dale/Introspection/Introspection.cpp index 9aeb4d93..32814a6b 100644 --- a/src/dale/Introspection/Introspection.cpp +++ b/src/dale/Introspection/Introspection.cpp @@ -869,20 +869,10 @@ bool eval_2D_expression(MContext *mc, DNode *type_form, DNode *form, units->top()->makeTemporaryGlobalFunction(); - std::vector active_ns_nodes = ctx->active_ns_nodes; - std::vector used_ns_nodes = ctx->used_ns_nodes; - if (!units->prefunction_ns) { - units->prefunction_ns = ctx->active_ns_nodes.front()->ns; - } - ctx->popUntilNamespace(units->prefunction_ns); - llvm::Constant *init = NULL; int size; init = FormValueParse(units, type, n, &size); - ctx->active_ns_nodes = active_ns_nodes; - ctx->used_ns_nodes = used_ns_nodes; - units->top()->removeTemporaryGlobalFunction(); int error_count_end = ctx->er->getErrorTypeCount(ErrorType::Error); diff --git a/src/dale/REPL/REPL.cpp b/src/dale/REPL/REPL.cpp index 1d191213..9c93ef75 100644 --- a/src/dale/REPL/REPL.cpp +++ b/src/dale/REPL/REPL.cpp @@ -297,7 +297,7 @@ bool REPLLoop(Units *units) { ctx->deactivateNamespace(anon_name.c_str()); if (!exists) { - res = ctx->ns()->addVariable(var_name.c_str(), var); + res = ctx->addVariable(var_name.c_str(), var); if (!res) { fprintf(stderr, "Internal error: cannot add variable.\n"); abort(); diff --git a/src/dale/Variable/Variable.cpp b/src/dale/Variable/Variable.cpp index a3df725b..4ddbc9f0 100644 --- a/src/dale/Variable/Variable.cpp +++ b/src/dale/Variable/Variable.cpp @@ -8,6 +8,7 @@ Variable::Variable() { linkage = Linkage::Auto; type = NULL; value = NULL; + fn = NULL; } Variable::Variable(const char *name, Type *type) { @@ -19,6 +20,7 @@ Variable::Variable(const char *name, Type *type) { serialise = true; linkage = Linkage::Auto; value = NULL; + fn = NULL; } Variable::~Variable() {} @@ -31,6 +33,7 @@ void Variable::copyTo(Variable *other) { other->once_tag = this->once_tag; other->index = this->index; other->linkage = this->linkage; + other->fn = this->fn; } bool Variable::isEqualTo(Variable *other) { diff --git a/src/dale/Variable/Variable.h b/src/dale/Variable/Variable.h index ee22959b..82889928 100644 --- a/src/dale/Variable/Variable.h +++ b/src/dale/Variable/Variable.h @@ -15,6 +15,8 @@ #include "llvm/Support/raw_ostream.h" namespace dale { +class Function; + /*! Variable A class for storing the details of a variable. @@ -42,6 +44,9 @@ class Variable { int linkage; /*! Whether the variable should be serialised. */ bool serialise; + /*! The function scope the variable is in. NULL if it's a global, or + * function scope is not applicable. */ + Function *fn; Variable(); /*! Construct a new variable with the given name and type. diff --git a/t/004namespace/009anonfn-scope.t b/t/004namespace/009anonfn-scope.t new file mode 100644 index 00000000..3617398c --- /dev/null +++ b/t/004namespace/009anonfn-scope.t @@ -0,0 +1,17 @@ +#!/usr/bin/env perl + +use warnings; +use strict; +$ENV{"DALE_TEST_ARGS"} ||= ""; +my $test_dir = $ENV{"DALE_TEST_DIR"} || "."; +$ENV{PATH} .= ":."; + +use Data::Dumper; +use Test::More tests => 1; + +my $res = `dalec $ENV{"DALE_TEST_ARGS"} $test_dir/t/src/anonfn-scope.dt -o anonfn-scope`; +is($res, "*Struct* exists\n*Struct* exists\n", "Got expected results"); + +`rm anonfn-scope`; + +1; diff --git a/t/009module/018dtm-noimport.t b/t/009module/018dtm-noimport.t index b21f4fe1..97df558f 100644 --- a/t/009module/018dtm-noimport.t +++ b/t/009module/018dtm-noimport.t @@ -17,7 +17,7 @@ my @res = ok((not @res), 'No compilation errors'); @res = map { chomp; $_ } `dalec $ENV{"DALE_TEST_ARGS"} $test_dir/t/src/dtm-noimport-user.dt 2>&1`; is_deeply(\@res, -["$test_dir/t/src/dtm-noimport-user.dt:8:19: error: variable not in scope: 'y'"], +["$test_dir/t/src/dtm-noimport-user.dt:8:19: error: variable not in scope or cannot be used as value: 'y'"], 'Got correct compilation errors'); `rm libdtm-noimport.bc`; diff --git a/t/error-src/anonymous-scopes.dt.errors b/t/error-src/anonymous-scopes.dt.errors index a00822ad..f09ad1bf 100644 --- a/t/error-src/anonymous-scopes.dt.errors +++ b/t/error-src/anonymous-scopes.dt.errors @@ -1 +1 @@ -./t/error-src/anonymous-scopes.dt:6:17: error: variable not in scope: 'var2' (see macro at 6:11) +./t/error-src/anonymous-scopes.dt:6:17: error: variable not in scope or cannot be used as value: 'var2' (see macro at 6:11) diff --git a/t/error-src/for-loop.dt.errors b/t/error-src/for-loop.dt.errors index 68600400..24d68cc4 100644 --- a/t/error-src/for-loop.dt.errors +++ b/t/error-src/for-loop.dt.errors @@ -1 +1 @@ -./t/error-src/for-loop.dt:6:25: error: variable not in scope: 'asdf' (see macro at 6:5) +./t/error-src/for-loop.dt:6:25: error: variable not in scope or cannot be used as value: 'asdf' (see macro at 6:5) diff --git a/t/error-src/invalid-intern-var.dt.errors b/t/error-src/invalid-intern-var.dt.errors index 9a4b2f4e..11db31f6 100644 --- a/t/error-src/invalid-intern-var.dt.errors +++ b/t/error-src/invalid-intern-var.dt.errors @@ -1,2 +1,2 @@ -t/error-src/invalid-intern-var.dt:5:32: error: variable not in scope: 'asdf' -t/error-src/invalid-intern-var.dt:6:17: error: variable not in scope: 'testvar' +t/error-src/invalid-intern-var.dt:5:32: error: variable not in scope or cannot be used as value: 'asdf' +t/error-src/invalid-intern-var.dt:6:17: error: variable not in scope or cannot be used as value: 'testvar' diff --git a/t/error-src/macro-error-position.dt.errors b/t/error-src/macro-error-position.dt.errors index e3366cd7..f8252c72 100644 --- a/t/error-src/macro-error-position.dt.errors +++ b/t/error-src/macro-error-position.dt.errors @@ -1,2 +1,2 @@ ./t/error-src/macro-error-position.dt:9:13: error: invalid type (see macro at 14:27) -./t/error-src/macro-error-position.dt:15:25: error: variable not in scope: 'a-string' +./t/error-src/macro-error-position.dt:15:25: error: variable not in scope or cannot be used as value: 'a-string' diff --git a/t/error-src/ml-comment-line-numbers.dt.errors b/t/error-src/ml-comment-line-numbers.dt.errors index b2fbbcec..03edd086 100644 --- a/t/error-src/ml-comment-line-numbers.dt.errors +++ b/t/error-src/ml-comment-line-numbers.dt.errors @@ -1 +1 @@ -./t/error-src/ml-comment-line-numbers.dt:19:3: error: variable not in scope: 'asdf' +./t/error-src/ml-comment-line-numbers.dt:19:3: error: variable not in scope or cannot be used as value: 'asdf' diff --git a/t/error-src/ml-string-line-numbers.dt.errors b/t/error-src/ml-string-line-numbers.dt.errors index c98756e4..f06e4914 100644 --- a/t/error-src/ml-string-line-numbers.dt.errors +++ b/t/error-src/ml-string-line-numbers.dt.errors @@ -1 +1 @@ -./t/error-src/ml-string-line-numbers.dt:15:3: error: variable not in scope: 'asdf' +./t/error-src/ml-string-line-numbers.dt:15:3: error: variable not in scope or cannot be used as value: 'asdf' diff --git a/t/error-src/no-vla.dt.errors b/t/error-src/no-vla.dt.errors index 6c59352d..2d74e5a4 100644 --- a/t/error-src/no-vla.dt.errors +++ b/t/error-src/no-vla.dt.errors @@ -1 +1 @@ -./t/error-src/no-vla.dt:3:30: error: variable not in scope: 'x' +./t/error-src/no-vla.dt:3:30: error: variable not in scope or cannot be used as value: 'x' diff --git a/t/error-src/qq-problems.dt.errors b/t/error-src/qq-problems.dt.errors index 7a328944..c49f0392 100644 --- a/t/error-src/qq-problems.dt.errors +++ b/t/error-src/qq-problems.dt.errors @@ -1,18 +1,18 @@ ./t/error-src/qq-problems.dt:6:11: error: only DNodes may be unquoted (see macro at 6:3) ./t/error-src/qq-problems.dt:6:3: error: macro expansion error (see previous) -./t/error-src/qq-problems.dt:7:11: error: variable not in scope: 'asdf' (see macro at 7:3) +./t/error-src/qq-problems.dt:7:11: error: variable not in scope or cannot be used as value: 'asdf' (see macro at 7:3) ./t/error-src/qq-problems.dt:7:3: error: macro expansion error (see previous) ./t/error-src/qq-problems.dt:8:12: error: only DNodes may be unquoted (see macro at 8:3) ./t/error-src/qq-problems.dt:8:3: error: macro expansion error (see previous) -./t/error-src/qq-problems.dt:9:12: error: variable not in scope: 'asdf' (see macro at 9:3) +./t/error-src/qq-problems.dt:9:12: error: variable not in scope or cannot be used as value: 'asdf' (see macro at 9:3) ./t/error-src/qq-problems.dt:9:3: error: macro expansion error (see previous) ./t/error-src/qq-problems.dt:10:14: error: only DNodes may be unquoted (see macro at 10:3) ./t/error-src/qq-problems.dt:10:3: error: macro expansion error (see previous) -./t/error-src/qq-problems.dt:11:14: error: variable not in scope: 'asdf' (see macro at 11:3) +./t/error-src/qq-problems.dt:11:14: error: variable not in scope or cannot be used as value: 'asdf' (see macro at 11:3) ./t/error-src/qq-problems.dt:11:3: error: macro expansion error (see previous) ./t/error-src/qq-problems.dt:12:15: error: only DNodes may be unquoted (see macro at 12:3) ./t/error-src/qq-problems.dt:12:3: error: macro expansion error (see previous) -./t/error-src/qq-problems.dt:13:15: error: variable not in scope: 'asdf' (see macro at 13:3) +./t/error-src/qq-problems.dt:13:15: error: variable not in scope or cannot be used as value: 'asdf' (see macro at 13:3) ./t/error-src/qq-problems.dt:13:3: error: macro expansion error (see previous) ./t/error-src/qq-problems.dt:17:9: error: unquoting null node (see macro at 17:5) ./t/error-src/qq-problems.dt:27:5: error: macro expansion error (see previous) diff --git a/t/src/anonfn-scope.dt b/t/src/anonfn-scope.dt new file mode 100644 index 00000000..c21d5784 --- /dev/null +++ b/t/src/anonfn-scope.dt @@ -0,0 +1,16 @@ +(import macros) + +(using-namespace std.macros + (def check-struct (macro intern (void) + (if (exists-type mc (mnfv mc "*Struct*")) + (printf "*Struct* exists\n") + (printf "*Struct* does not exist\n")) + (nullptr DNode)))) + +(def main (fn extern-c int (void) + (def *Struct* (struct intern ((a int)))) + (check-struct) + (def anon-func (var auto \ (fn void (void) + (check-struct)))) + 0)) +