diff --git a/modcc/parser.cpp b/modcc/parser.cpp
index 55960aa3cd9a3fe547499f9d1c48c92286ccf109..753b0b80c3892c71f810f48e73176d1773ebee25 100644
--- a/modcc/parser.cpp
+++ b/modcc/parser.cpp
@@ -399,9 +399,16 @@ void Parser::parse_state_block() {
         }
 
         parm.token = token_;
-        //state_block.state_variables.push_back(token_.spelling);
         get_token();
 
+        if(token_.type == tok::from) {
+            // silently skips from/to
+            from_to_description();
+            if (status_ == lexerStatus::error) {
+                return;
+            }
+        }
+
         // get unit parameters
         if (line == location_.line && token_.type == tok::lparen) {
             parm.units = unit_description();
@@ -763,6 +770,10 @@ std::pair<Token, Token> Parser::range_description() {
     }
 
     get_token();
+    if(token_.type != tok::integer) {
+        error(pprintf("range description must be <int, int>, found '%'", token_));
+        return {};
+    }
     lb = token_;
 
     get_token();
@@ -772,6 +783,10 @@ std::pair<Token, Token> Parser::range_description() {
     }
 
     get_token();
+    if(token_.type != tok::integer) {
+        error(pprintf("range description must be <int, int>, found '%'", token_));
+        return {};
+    }
     ub = token_;
 
     get_token();
@@ -784,6 +799,39 @@ std::pair<Token, Token> Parser::range_description() {
     return {lb, ub};
 }
 
+std::pair<Token, Token> Parser::from_to_description() {
+    Token lb, ub;
+
+    if(token_.type != tok::from) {
+        error(pprintf("range description must be of form FROM <int> TO <int>, found '%'", token_));
+        return {};
+    }
+
+    get_token();
+    if(token_.type != tok::integer) {
+        error(pprintf("range description must be of form FROM <int> TO <int>, found '%'", token_));
+        return {};
+    }
+    lb = token_;
+
+    get_token();
+    if(token_.type != tok::to) {
+        error(pprintf("range description must be of form FROM <int> TO <int>, found '%'", token_));
+        return {};
+    }
+
+    get_token();
+    if(token_.type != tok::integer) {
+        error(pprintf("range description must be of form FROM <int> TO <int>, found '%'", token_));
+        return {};
+    }
+    ub = token_;
+
+    get_token();
+    return {lb, ub};
+}
+
+
 // Returns a prototype expression for a function or procedure call
 // Takes an optional argument that allows the user to specify the
 // name of the prototype, which is used for prototypes where the name
@@ -804,7 +852,6 @@ expression_ptr Parser::parse_prototype(std::string name=std::string()) {
     // check for an argument list enclosed in parenthesis (...)
     // return a prototype with an empty argument list if not found
     if( token_.type != tok::lparen ) {
-        //return make_expression<PrototypeExpression>(identifier.location, identifier.spelling, {});
         return expression_ptr{new PrototypeExpression(identifier.location, identifier.spelling, {})};
     }
 
@@ -822,6 +869,14 @@ expression_ptr Parser::parse_prototype(std::string name=std::string()) {
 
         get_token(); // consume the identifier
 
+        // args may have a unit attached
+        if(token_.type == tok::lparen) {
+            unit_description();
+            if(status_ == lexerStatus::error) {
+                return {};
+            }
+        }
+
         // look for a comma
         if(!(token_.type == tok::comma || token_.type==tok::rparen)) {
             error(  "expected a comma or closing parenthesis, found '"
diff --git a/modcc/parser.hpp b/modcc/parser.hpp
index 49512f7ef5053926438494f9544afacca09f8237..a250ee8c5b6a6b866e65604b176d175cae993dd6 100644
--- a/modcc/parser.hpp
+++ b/modcc/parser.hpp
@@ -69,6 +69,7 @@ private:
     std::string value_literal();
     int value_signed_integer();
     std::pair<Token, Token> range_description();
+    std::pair<Token, Token> from_to_description();
 
     /// build the identifier list
     void add_variables_to_symbols();
diff --git a/modcc/token.cpp b/modcc/token.cpp
index 8348a6e8a219ba3c9b5f16850cfdfb81b7586610..30ed8def41408a16c6f37022d4d1a7b021a0cd75 100644
--- a/modcc/token.cpp
+++ b/modcc/token.cpp
@@ -54,6 +54,8 @@ static Keyword keywords[] = {
     {"COMPARTMENT", tok::compartment},
     {"METHOD",      tok::method},
     {"STEADYSTATE", tok::steadystate},
+    {"FROM",        tok::from},
+    {"TO",          tok::to},
     {"if",          tok::if_stmt},
     {"IF",          tok::if_stmt},
     {"else",        tok::else_stmt},
diff --git a/modcc/token.hpp b/modcc/token.hpp
index 3c5344a49b461c1c8d2fb827e83f924ac7dd99e1..21648dcdb84a0094be95eeb02c0b18b1e5c927ce 100644
--- a/modcc/token.hpp
+++ b/modcc/token.hpp
@@ -64,6 +64,7 @@ enum class tok {
     solve, method, steadystate,
     threadsafe, global,
     point_process,
+    from, to,
 
     // prefix binary operators
     min, max,
diff --git a/test/unit-modcc/test_parser.cpp b/test/unit-modcc/test_parser.cpp
index 11e6e51b8a90eae3c306dd3460194837718e80ac..10952756306fb90b3866f55cd9f4e89399c2ccfa 100644
--- a/test/unit-modcc/test_parser.cpp
+++ b/test/unit-modcc/test_parser.cpp
@@ -93,7 +93,7 @@ TEST(Parser, procedure) {
         "  y = a + b *c + a + b\n"
         "}"
         ,
-        "PROCEDURE trates(v) {\n"
+        "PROCEDURE trates(v (mV)) {\n"
         "    LOCAL qt\n"
         "    qt=q10^((celsius-22)/10)\n"
         "    minf=1-1/(1+exp((v-vhalfm)/km))\n"
@@ -685,6 +685,10 @@ TEST(Parser, parse_state_block) {
         "STATE {\n"
         "    h (nA)\n"
         "    m (nA) r (uA)\n"
+        "}",
+        "STATE {\n"
+        "    h FROM 0 TO 1\n"
+        "    m r (uA)\n"
         "}"
     };