From 85667336a18ea1a03bdb2d4071bcd93edc07094f Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 12 Aug 2013 17:24:47 -0400 Subject: [PATCH] macroprocessor: add length command. closes #436 --- doc/dynare.texi | 5 +++++ preprocessor/macro/MacroBison.yy | 6 ++++-- preprocessor/macro/MacroFlex.ll | 3 ++- preprocessor/macro/MacroValue.cc | 8 +++++++- preprocessor/macro/MacroValue.hh | 13 ++++++++++++- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/doc/dynare.texi b/doc/dynare.texi index ed04c7bc8..ea02204c9 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -7219,6 +7219,11 @@ extraction of sub-arrays: @i{e.g.} @code{@var{v}[4:6]} @item testing membership of an array: @code{in} operator (for example: @code{"b" in ["a", "b", "c"]} returns @code{1}) +@item +getting the length of an array: @code{length} operator (for example: +@code{length(["a", "b", "c"])} returns @code{3} and, hence, +@code{1:length(["a", "b", "c"])} is equivalent to integer array +@code{[1,2,3]}) @end itemize Macro-expressions can be used at two places: diff --git a/preprocessor/macro/MacroBison.yy b/preprocessor/macro/MacroBison.yy index a7dc4fc5c..a7a6456e8 100644 --- a/preprocessor/macro/MacroBison.yy +++ b/preprocessor/macro/MacroBison.yy @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Dynare Team + * Copyright (C) 2008-2013 Dynare Team * * This file is part of Dynare. * @@ -80,7 +80,7 @@ class MacroDriver; %} %token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF IFNDEF -%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL +%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH %token INTEGER %token NAME STRING @@ -145,6 +145,8 @@ expr : INTEGER } delete $1; } + | LENGTH LPAREN array_expr RPAREN + { TYPERR_CATCH($$ = $3->length(), @$); } | LPAREN expr RPAREN { $$ = $2; } | expr PLUS expr diff --git a/preprocessor/macro/MacroFlex.ll b/preprocessor/macro/MacroFlex.ll index 7e3e5dbae..05a60329c 100644 --- a/preprocessor/macro/MacroFlex.ll +++ b/preprocessor/macro/MacroFlex.ll @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Dynare Team + * Copyright (C) 2008-2013 Dynare Team * * This file is part of Dynare. * @@ -151,6 +151,7 @@ CONT \\\\ [*] { return token::TIMES; } [/] { return token::DIVIDE; } in { return token::IN; } +length { return token::LENGTH; } \"[^\"]*\" { yylval->string_val = new string(yytext + 1); diff --git a/preprocessor/macro/MacroValue.cc b/preprocessor/macro/MacroValue.cc index 646f6d8a1..65b3fc39d 100644 --- a/preprocessor/macro/MacroValue.cc +++ b/preprocessor/macro/MacroValue.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 Dynare Team + * Copyright (C) 2008-2013 Dynare Team * * This file is part of Dynare. * @@ -106,6 +106,12 @@ MacroValue::operator[](const MacroValue &mv) const throw (TypeError, OutOfBounds throw TypeError("Operator [] does not exist for this type"); } +const MacroValue * +MacroValue::length() const throw (TypeError) +{ + throw TypeError("Length not supported for this type"); +} + const MacroValue * MacroValue::append(const MacroValue *mv) const throw (TypeError) { diff --git a/preprocessor/macro/MacroValue.hh b/preprocessor/macro/MacroValue.hh index 0704b555f..d79c024c5 100644 --- a/preprocessor/macro/MacroValue.hh +++ b/preprocessor/macro/MacroValue.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2010 Dynare Team + * Copyright (C) 2008-2013 Dynare Team * * This file is part of Dynare. * @@ -92,6 +92,8 @@ public: virtual string toString() const = 0; //! Converts value to array form virtual const MacroValue *toArray() const = 0; + //! Gets length + virtual const MacroValue *length() const throw (TypeError); //! Appends value at the end of an array /*! The argument must be an array. */ virtual const MacroValue *append(const MacroValue *array) const throw (TypeError); @@ -217,6 +219,8 @@ public: virtual string toString() const; //! Returns itself virtual const MacroValue *toArray() const; + //! Gets length + virtual const MacroValue *length() const throw (TypeError); }; template @@ -329,4 +333,11 @@ ArrayMV::toArray() const return this; } +template +const MacroValue * +ArrayMV::length() const throw (TypeError) +{ + return new IntMV(driver, values.size()); +} + #endif