diff --git a/modcc/blocks.hpp b/modcc/blocks.hpp index 9ba8c65769f97afe631b8d9fc7779b4472758b4f..868f60bd601ba914d8f86f07e6294bd353d12b19 100644 --- a/modcc/blocks.hpp +++ b/modcc/blocks.hpp @@ -17,6 +17,7 @@ struct IonDep { std::string name; // name of ion channel std::vector<Token> read; // name of channels parameters to write std::vector<Token> write; // name of channels parameters to read + std::string valence; bool has_variable(std::string const& name) const { return writes_variable(name) || reads_variable(name); diff --git a/modcc/functioninliner.cpp b/modcc/functioninliner.cpp index da5dd5eb270fbb11f17e8a553687e57dbc1ea026..20c0c2ede1394a57f065c125192f6deab76a0bd2 100644 --- a/modcc/functioninliner.cpp +++ b/modcc/functioninliner.cpp @@ -18,6 +18,13 @@ expression_ptr inline_function_call(Expression* e) "can only inline functions with one statement", func->location() ); } + + if(body.front()->is_if()) { + throw compiler_exception( + "can not inline functions with if statements", func->location() + ); + } + // assume that the function body is correctly formed, with the last // statement being an assignment expression auto last = body.front()->is_assignment(); diff --git a/modcc/module.cpp b/modcc/module.cpp index c78d9c7253c9b766ec67d65c37d27d75d6bbe059..97debcad3542b94e58fb3732bbb40f33d203f877 100644 --- a/modcc/module.cpp +++ b/modcc/module.cpp @@ -590,7 +590,11 @@ void Module::add_variables_to_symbols() { VariableExpression* state = nullptr; if (has_symbol(name)) { state = symbols_[name].get()->is_variable(); - if (!state || !state->is_state()) { + if (!state) { + error(pprintf("the symbol defined % can't be redeclared", yellow(name)), tkn.location); + return; + } + if (!state->is_state()) { error(pprintf("the symbol defined % at % can't be redeclared", state->location(), yellow(name)), tkn.location); return; diff --git a/modcc/parser.cpp b/modcc/parser.cpp index 6ce9258b1ca4a500a275df2529e3646ac0c1bbbd..1598711a9c919a37b8d8b74e33292e5af82e9a40 100644 --- a/modcc/parser.cpp +++ b/modcc/parser.cpp @@ -35,6 +35,15 @@ bool Parser::expect(tok tok, std::string const& str) { return false; } +void Parser::parse_unit() { + if(token_.type == tok::lparen) { + while (token_.type != tok::rparen) { + get_token(); + } + get_token(); // consume ')' + } +} + void Parser::error(std::string msg) { std::string location_info = pprintf( "%:% ", module_ ? module_->source_name() : "", token_.location); @@ -125,6 +134,12 @@ bool Parser::parse() { module_->add_callable(std::move(f)); } break; + case tok::unitson : + get_token(); + break; + case tok::unitsoff : + get_token(); + break; default : error(pprintf("expected block type, found '%'", token_.spelling)); break; @@ -317,6 +332,13 @@ void Parser::parse_neuron_block() { target.push_back(id); } } + + if(token_.type == tok::valence) { + //Consume "Valence" + get_token(); + ion.valence == value_literal(); + } + // add the ion dependency to the NEURON block neuron_block.ions.push_back(std::move(ion)); } @@ -715,6 +737,8 @@ expression_ptr Parser::parse_prototype(std::string name=std::string()) { get_token(); // consume the identifier + parse_unit(); // consume the unit if provided + // look for a comma if(!(token_.type == tok::comma || token_.type==tok::rparen)) { error( "expected a comma or closing parenthesis, found '" @@ -839,6 +863,8 @@ symbol_ptr Parser::parse_function() { auto p = parse_prototype(); if(p==nullptr) return nullptr; + parse_unit(); + // check for opening left brace { if(!expect(tok::lbrace)) return nullptr; diff --git a/modcc/parser.hpp b/modcc/parser.hpp index 43fb323b2d632ebf571636770a3abe6a241ca5af..8b9414237db2948a899eeed990881b08d93c8e6f 100644 --- a/modcc/parser.hpp +++ b/modcc/parser.hpp @@ -75,6 +75,7 @@ private: Parser(); Parser(Parser const &); + void parse_unit(); bool expect(tok, const char *str=""); bool expect(tok, std::string const& str); }; diff --git a/modcc/token.cpp b/modcc/token.cpp index 1ea8d27abf2a4f20305661e995ee57ac1e961c29..ba89e2ce8447492d1e79add7e5ad18fd4767282b 100644 --- a/modcc/token.cpp +++ b/modcc/token.cpp @@ -41,6 +41,7 @@ static Keyword keywords[] = { {"USEION", tok::useion}, {"READ", tok::read}, {"WRITE", tok::write}, + {"VALENCE", tok::valence}, {"RANGE", tok::range}, {"LOCAL", tok::local}, {"CONSERVE", tok::conserve}, @@ -110,6 +111,7 @@ static TokenString token_strings[] = { {"USEION", tok::useion}, {"READ", tok::read}, {"WRITE", tok::write}, + {"VALENCE", tok::valence}, {"RANGE", tok::range}, {"LOCAL", tok::local}, {"SOLVE", tok::solve}, diff --git a/modcc/token.hpp b/modcc/token.hpp index 97667c2eb660c81d795e742d99bf917e0d84c994..149ee7435cdda2c6a4235a99a559ba7ddd735b19 100644 --- a/modcc/token.hpp +++ b/modcc/token.hpp @@ -59,7 +59,7 @@ enum class tok { // keywoards inside blocks unitsoff, unitson, suffix, nonspecific_current, useion, - read, write, + read, write, valence, range, local, conserve, solve, method, threadsafe, global,