Ivo, FWIW there is an old branch of R with optional types which was part of the R5 experiment (to declare R5 method argument types more intuitively):
https://svn.r-project.org/R/branches/R-exp-R5/ The parser has changed a bit in the meantime so attached is diff against the current R-devel if you want to play with it. This allows the following syntax: > f <- function(a, character x, integer y=1:10) x > str(formals(f)) Dotted pair list of 3 $ a: symbol $ x: symbol $ y: language 1:10 - attr(*, "type")=List of 3 ..$ : NULL ..$ : symbol character ..$ : symbol integer It doesn't actually do anything with the information, just allows to tag the formals so you can play with ideas at the R level. Cheers, Simon -- cut here -- Index: src/include/Defn.h =================================================================== --- src/include/Defn.h (revision 89063) +++ src/include/Defn.h (working copy) @@ -756,6 +756,10 @@ SEXP R_tryWrap(SEXP); SEXP R_tryUnwrap(SEXP); +/* experimental argument type macros */ +#define SET_ARGTYPE(x, type) Rf_setAttrib(x, R_TypeSymbol, type) +#define GET_ARGTYPE(x) Rf_getAttrib(x, R_TypeSymbol) + Rboolean Rf_pmatch(SEXP, SEXP, Rboolean); Rboolean Rf_psmatch(const char *, const char *, Rboolean); void Rf_printwhere(void); Index: src/include/Rinternals.h =================================================================== --- src/include/Rinternals.h (revision 89063) +++ src/include/Rinternals.h (working copy) @@ -457,6 +457,7 @@ LibExtern SEXP R_SpecSymbol; // "spec" LibExtern SEXP R_TripleColonSymbol;// ":::" LibExtern SEXP R_TspSymbol; /* "tsp" */ +LibExtern SEXP R_TypeSymbol; /* "type" */ LibExtern SEXP R_dot_defined; /* ".defined" */ LibExtern SEXP R_dot_Method; /* ".Method" */ Index: src/main/gram.c =================================================================== --- src/main/gram.c (revision 89063) +++ src/main/gram.c (working copy) @@ -241,6 +241,7 @@ static void CheckFormalArgs(SEXP, SEXP, YYLTYPE *); static SEXP FirstArg(SEXP, SEXP); /* create list with one element */ +static SEXP FirstArgWithType(SEXP, SEXP, SEXP); static void GrowList(SEXP, SEXP); /* add element to list end */ static void SetSingleSrcRef(SEXP); @@ -252,6 +253,7 @@ static int KeywordLookup(const char *); static SEXP NewList(void); static void NextArg(SEXP, SEXP, SEXP); /* add named element to list end */ +static void NextArgWithType(SEXP, SEXP, SEXP, SEXP); static SEXP TagArg(SEXP, SEXP, YYLTYPE *); static int processLineDirective(int *); static bool checkForPlaceholder(SEXP placeholder, SEXP arg); @@ -427,8 +429,12 @@ static SEXP xxnullformal(void); static SEXP xxfirstformal0(SEXP); static SEXP xxfirstformal1(SEXP, SEXP); +static SEXP xxfirstformal2(SEXP, SEXP); +static SEXP xxfirstformal3(SEXP, SEXP, SEXP); static SEXP xxaddformal0(SEXP, SEXP, YYLTYPE *); static SEXP xxaddformal1(SEXP, SEXP, SEXP, YYLTYPE *); +static SEXP xxaddformal2(SEXP, SEXP, SEXP, YYLTYPE *); +static SEXP xxaddformal3(SEXP, SEXP, SEXP, SEXP, YYLTYPE *); static SEXP xxexprlist0(void); static SEXP xxexprlist1(SEXP, YYLTYPE *); static SEXP xxexprlist2(SEXP, SEXP, YYLTYPE *); @@ -557,62 +563,6 @@ }; typedef enum yytokentype yytoken_kind_t; #endif -/* Token kinds. */ -#define YYEMPTY -2 -#define YYEOF 0 -#define YYerror 256 -#define YYUNDEF 257 -#define END_OF_INPUT 258 -#define ERROR 259 -#define STR_CONST 260 -#define NUM_CONST 261 -#define NULL_CONST 262 -#define SYMBOL 263 -#define FUNCTION 264 -#define INCOMPLETE_STRING 265 -#define LEFT_ASSIGN 266 -#define EQ_ASSIGN 267 -#define RIGHT_ASSIGN 268 -#define LBB 269 -#define FOR 270 -#define IN 271 -#define IF 272 -#define ELSE 273 -#define WHILE 274 -#define NEXT 275 -#define BREAK 276 -#define REPEAT 277 -#define GT 278 -#define GE 279 -#define LT 280 -#define LE 281 -#define EQ 282 -#define NE 283 -#define AND 284 -#define OR 285 -#define AND2 286 -#define OR2 287 -#define NS_GET 288 -#define NS_GET_INT 289 -#define COMMENT 290 -#define LINE_DIRECTIVE 291 -#define SYMBOL_FORMALS 292 -#define EQ_FORMALS 293 -#define EQ_SUB 294 -#define SYMBOL_SUB 295 -#define SYMBOL_FUNCTION_CALL 296 -#define SYMBOL_PACKAGE 297 -#define SLOT 298 -#define PIPE 299 -#define PLACEHOLDER 300 -#define PIPEBIND 301 -#define LOW 302 -#define TILDE 303 -#define UNOT 304 -#define NOT 305 -#define SPECIAL 306 -#define UMINUS 307 -#define UPLUS 308 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED @@ -1065,7 +1015,7 @@ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 48 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 572 +#define YYLAST 601 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 75 @@ -1072,9 +1022,9 @@ /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 13 /* YYNRULES -- Number of rules. */ -#define YYNRULES 94 +#define YYNRULES 98 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 174 +#define YYNSTATES 180 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 308 @@ -1128,16 +1078,16 @@ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 446, 446, 447, 448, 449, 450, 453, 454, 455, - 458, 459, 462, 463, 464, 465, 466, 468, 469, 471, - 472, 473, 474, 475, 477, 478, 479, 480, 481, 482, - 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, - 493, 494, 495, 496, 497, 498, 499, 501, 502, 503, - 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, - 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, - 527, 530, 533, 537, 538, 539, 540, 541, 542, 545, - 546, 549, 550, 551, 552, 553, 554, 555, 556, 559, - 560, 561, 562, 563, 567 + 0, 452, 452, 453, 454, 455, 456, 459, 460, 461, + 464, 465, 468, 469, 470, 471, 472, 474, 475, 477, + 478, 479, 480, 481, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, + 499, 500, 501, 502, 503, 504, 505, 507, 508, 509, + 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, + 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, + 533, 536, 539, 543, 544, 545, 546, 547, 548, 551, + 552, 555, 556, 557, 558, 559, 560, 561, 562, 565, + 566, 567, 568, 569, 571, 572, 574, 575, 578 }; #endif @@ -1176,7 +1126,7 @@ } #endif -#define YYPACT_NINF (-130) +#define YYPACT_NINF (-138) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -1190,24 +1140,24 @@ STATE-NUM. */ static const yytype_int16 yypact[] = { - 139, -130, -130, -11, -130, -130, 2, -49, 10, 27, - 29, -130, -130, 209, -130, 209, 209, 209, 209, 209, - -130, 209, 209, 30, 95, 14, 281, 16, 70, 71, - 77, 88, 89, 209, 209, 209, 209, 209, 86, 86, - 371, 225, 225, 13, 18, -53, 440, 88, -130, 209, - 209, -130, -130, 209, 209, 229, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 82, 84, 229, 229, - -130, -130, -130, -130, -130, -130, -130, -130, 87, -3, - 90, 86, -43, 281, -1, -39, 86, -130, 209, 209, - -130, 3, 86, 86, 281, 326, -5, 91, 0, 55, - 31, -130, 485, 485, 485, 485, 485, 485, 440, 416, - 440, 416, 206, 107, 371, 118, 118, 507, 507, 206, - 225, 225, -130, -130, -130, -130, 35, 36, 209, -130, - 100, 209, 209, -130, 209, -130, 18, 18, -130, 209, - 209, 209, 39, 40, -130, -130, 55, 209, 101, -38, - -130, 86, 209, 55, 55, 55, -130, 229, 86, 209, - -130, 86, -130, 55 + 192, -138, -138, 44, -138, -138, 70, -55, -48, -35, + -28, -138, -138, 212, -138, 212, 212, 212, 212, 212, + -138, 212, 212, 15, 22, 14, 332, 82, 84, 86, + 88, 16, 77, 212, 212, 212, 212, 212, 85, 85, + 422, 68, 68, 13, 21, 7, 491, 16, -138, 212, + 212, -138, -138, 212, 212, 280, 212, 212, 212, 212, + 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 212, 212, 212, 90, 94, 280, 280, + -138, -138, -138, -138, -138, -138, -138, -138, 3, -53, + 91, 85, -43, 332, -4, -42, 85, -138, 212, 212, + -138, -51, 85, 85, 332, 377, -2, 96, 1, 62, + 37, -138, 536, 536, 536, 536, 536, 536, 491, 467, + 491, 467, 114, 55, 422, 248, 248, 101, 101, 114, + 68, 68, -138, -138, -138, -138, 41, 39, 102, 212, + -138, 113, 212, 212, -138, 212, -138, 21, 21, -138, + 212, 212, 212, 49, 50, -138, -138, 212, 62, 212, + 63, -40, -138, 85, 212, 62, 62, 62, -138, 280, + 62, 85, 125, 212, -138, 85, -138, 212, 62, 62 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1226,20 +1176,20 @@ 59, 58, 63, 62, 57, 56, 61, 60, 90, 0, 0, 51, 0, 10, 49, 0, 52, 18, 78, 76, 17, 0, 8, 9, 44, 45, 13, 14, 16, 82, - 94, 79, 37, 36, 32, 33, 34, 35, 38, 39, + 98, 79, 37, 36, 32, 33, 34, 35, 38, 39, 40, 41, 42, 43, 31, 25, 26, 27, 28, 30, - 24, 29, 65, 64, 67, 66, 94, 94, 0, 94, - 0, 0, 0, 71, 0, 70, 77, 75, 94, 85, - 87, 83, 0, 0, 48, 55, 91, 0, 92, 0, - 11, 50, 0, 86, 88, 84, 54, 81, 46, 0, - 72, 47, 80, 93 + 24, 29, 65, 64, 67, 66, 98, 98, 92, 0, + 98, 0, 0, 0, 71, 0, 70, 77, 75, 98, + 85, 87, 83, 0, 0, 48, 55, 0, 91, 0, + 94, 0, 11, 50, 0, 86, 88, 84, 54, 81, + 93, 46, 96, 0, 72, 47, 80, 0, 95, 97 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -130, -130, 51, -31, -16, -130, -130, -130, -130, -10, - -52, 69, -129 + -138, -138, 51, 31, -16, -138, -138, -138, -138, 27, + -44, 92, -137 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -1246,7 +1196,7 @@ static const yytype_uint8 yydefgoto[] = { 0, 24, 25, 109, 26, 37, 35, 33, 45, 110, - 111, 89, 153 + 111, 89, 154 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1254,126 +1204,132 @@ number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 40, 41, 42, 92, 142, 95, 46, 149, 142, 142, - 157, 49, 151, 98, 99, 31, 100, 144, 93, 162, - 93, 80, 27, 28, 81, 49, 49, 143, 27, 28, - 49, 145, 170, 29, 30, 29, 30, 104, 105, 93, + 40, 41, 42, 159, 143, 143, 46, 143, 49, 31, + 150, 138, 164, 152, 145, 139, 32, 140, 93, 149, + 93, 141, 48, 141, 88, 49, 49, 144, 146, 34, + 174, 27, 28, 49, 29, 30, 36, 104, 105, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 50, 50, 93, 93, 38, 50, 39, 139, 136, 137, - 43, 140, 44, 148, 32, 82, 84, 140, 83, 85, - 51, 52, 86, 97, 91, 87, 94, 132, 96, 134, - 133, 34, 135, 36, 47, 48, 88, 90, 49, 138, - 102, 103, 142, 150, 152, 154, 141, 156, 158, 155, - 159, 160, 166, 169, 167, 172, 101, 0, 163, 164, - 165, 55, 93, 0, 0, 93, 93, 0, 0, 0, - 0, 0, 55, 93, 93, 93, 0, 0, 173, 0, - 1, 0, 2, 0, 3, 4, 5, 6, 7, 146, - 147, 93, 0, 93, 8, 0, 9, 0, 10, 11, - 12, 13, 66, 0, 67, 74, 0, 0, 75, 76, - 77, 78, 79, 71, 72, 73, 74, 0, 0, 75, - 76, 77, 78, 79, 14, 0, 15, 0, 16, 0, - 0, 0, 17, 18, 0, 161, 0, 0, 0, 0, - 0, 0, 0, 19, 0, 20, 0, 21, 168, 0, - 22, 23, 0, 171, 3, 4, 5, 6, 7, 0, - 55, 0, 0, 0, 8, 0, 9, 0, 10, 11, - 12, 13, 0, 0, 106, 4, 107, 108, 7, 55, - 0, 0, 0, 0, 8, 0, 9, 0, 10, 11, - 12, 13, 67, 0, 14, 0, 15, 0, 16, 0, - 0, 0, 17, 18, 74, 0, 0, 75, 76, 77, - 78, 79, 0, 19, 14, 0, 15, 21, 16, 0, - 22, 23, 17, 18, 0, 0, 75, 76, 77, 78, - 79, 0, 53, 19, 54, 55, 0, 21, 0, 0, - 22, 23, 0, 0, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 66, 0, 67, 0, 0, - 68, 0, 0, 0, 69, 70, 71, 72, 73, 74, - 55, 0, 75, 76, 77, 78, 79, 0, 0, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 0, + 50, 50, 93, 93, 38, 92, 39, 95, 50, 55, + 43, 172, 44, 98, 99, 173, 100, 27, 28, 47, + 51, 52, 55, 97, 91, 90, 94, 80, 96, 82, + 81, 84, 83, 86, 85, 132, 87, 49, 133, 134, + 102, 103, 135, 29, 30, 136, 137, 142, 151, 143, + 153, 155, 156, 74, 157, 55, 75, 76, 77, 78, + 79, 160, 168, 93, 169, 176, 93, 93, 55, 75, + 76, 77, 78, 79, 93, 93, 93, 177, 0, 101, + 0, 93, 0, 0, 0, 66, 0, 67, 0, 147, + 148, 0, 0, 93, 0, 0, 0, 93, 73, 74, + 67, 93, 75, 76, 77, 78, 79, 0, 0, 0, + 158, 0, 74, 161, 162, 75, 76, 77, 78, 79, + 0, 165, 166, 167, 0, 0, 0, 0, 170, 0, + 0, 0, 0, 1, 0, 2, 163, 3, 4, 5, + 6, 7, 0, 0, 178, 0, 0, 8, 179, 9, + 171, 10, 11, 12, 13, 175, 0, 3, 4, 5, + 6, 7, 0, 0, 0, 0, 0, 8, 0, 9, + 0, 10, 11, 12, 13, 0, 0, 14, 0, 15, + 0, 16, 0, 0, 0, 17, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 19, 14, 20, 15, + 21, 16, 55, 22, 23, 17, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, + 21, 0, 0, 22, 23, 106, 4, 107, 108, 7, + 0, 0, 66, 0, 67, 8, 0, 9, 0, 10, + 11, 12, 13, 71, 72, 73, 74, 0, 0, 75, + 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 14, 0, 15, 0, 16, + 0, 0, 0, 17, 18, 0, 0, 0, 0, 0, + 0, 0, 0, 53, 19, 54, 55, 0, 21, 0, + 0, 22, 23, 0, 0, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 66, 0, 67, 0, + 0, 68, 0, 0, 0, 69, 70, 71, 72, 73, + 74, 55, 0, 75, 76, 77, 78, 79, 0, 0, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 66, 0, 67, 0, 0, 68, 0, 0, 0, 69, - 70, 71, 72, 73, 74, 55, 0, 75, 76, 77, - 78, 79, 0, 0, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 66, 0, 67, 0, 0, + 0, 66, 0, 67, 0, 0, 68, 0, 0, 0, + 69, 70, 71, 72, 73, 74, 55, 0, 75, 76, + 77, 78, 79, 0, 0, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 66, 0, 67, 0, + 0, 0, 0, 0, 0, 69, 70, 71, 72, 73, + 74, 55, 0, 75, 76, 77, 78, 79, 0, 0, + 56, 57, 58, 59, 60, 61, 62, 0, 64, 0, + 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, + 0, 66, 0, 67, 56, 57, 58, 59, 60, 61, + 69, 70, 71, 72, 73, 74, 0, 0, 75, 76, + 77, 78, 79, 0, 0, 66, 0, 67, 0, 0, 0, 0, 0, 0, 69, 70, 71, 72, 73, 74, - 55, 0, 75, 76, 77, 78, 79, 0, 0, 56, - 57, 58, 59, 60, 61, 62, 0, 64, 0, 0, - 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, - 66, 0, 67, 56, 57, 58, 59, 60, 61, 69, + 55, 0, 75, 76, 77, 78, 79, 0, 0, -1, + -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 66, 0, 67, 0, 0, 0, 0, 0, 0, 69, 70, 71, 72, 73, 74, 0, 0, 75, 76, 77, - 78, 79, 0, 0, 66, 0, 67, 0, 0, 0, - 0, 0, 0, 69, 70, 71, 72, 73, 74, 55, - 0, 75, 76, 77, 78, 79, 0, 0, -1, -1, - -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, - 0, 55, 0, 0, 0, 0, 0, 0, 0, 66, - 0, 67, 0, 0, 0, 0, 0, 0, 69, 70, - 71, 72, 73, 74, 0, 0, 75, 76, 77, 78, - 79, 66, 0, 67, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 73, 74, 0, 0, 75, 76, - 77, 78, 79 + 78, 79 }; static const yytype_int16 yycheck[] = { - 16, 17, 18, 34, 47, 36, 22, 12, 47, 47, - 139, 12, 12, 66, 67, 64, 69, 18, 34, 148, - 36, 5, 33, 34, 8, 12, 12, 70, 33, 34, - 12, 70, 70, 33, 34, 33, 34, 53, 54, 55, + 16, 17, 18, 140, 47, 47, 22, 47, 12, 64, + 12, 8, 149, 12, 18, 12, 64, 70, 34, 70, + 36, 74, 0, 74, 8, 12, 12, 70, 70, 64, + 70, 33, 34, 12, 33, 34, 64, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 47, 47, 78, 79, 13, 47, 15, 70, 78, 79, - 19, 74, 21, 70, 64, 5, 5, 74, 8, 8, - 66, 67, 5, 70, 33, 8, 35, 5, 37, 5, - 8, 64, 8, 64, 64, 0, 8, 8, 12, 12, - 49, 50, 47, 12, 73, 70, 16, 138, 8, 73, - 141, 142, 73, 12, 74, 167, 47, -1, 149, 150, - 151, 14, 138, -1, -1, 141, 142, -1, -1, -1, - -1, -1, 14, 149, 150, 151, -1, -1, 169, -1, - 1, -1, 3, -1, 5, 6, 7, 8, 9, 98, - 99, 167, -1, 169, 15, -1, 17, -1, 19, 20, - 21, 22, 44, -1, 46, 58, -1, -1, 61, 62, - 63, 64, 65, 55, 56, 57, 58, -1, -1, 61, - 62, 63, 64, 65, 45, -1, 47, -1, 49, -1, - -1, -1, 53, 54, -1, 144, -1, -1, -1, -1, - -1, -1, -1, 64, -1, 66, -1, 68, 157, -1, - 71, 72, -1, 162, 5, 6, 7, 8, 9, -1, - 14, -1, -1, -1, 15, -1, 17, -1, 19, 20, - 21, 22, -1, -1, 5, 6, 7, 8, 9, 14, - -1, -1, -1, -1, 15, -1, 17, -1, 19, 20, - 21, 22, 46, -1, 45, -1, 47, -1, 49, -1, - -1, -1, 53, 54, 58, -1, -1, 61, 62, 63, - 64, 65, -1, 64, 45, -1, 47, 68, 49, -1, - 71, 72, 53, 54, -1, -1, 61, 62, 63, 64, - 65, -1, 11, 64, 13, 14, -1, 68, -1, -1, - 71, 72, -1, -1, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 44, -1, 46, -1, -1, - 49, -1, -1, -1, 53, 54, 55, 56, 57, 58, - 14, -1, 61, 62, 63, 64, 65, -1, -1, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, + 47, 47, 78, 79, 13, 34, 15, 36, 47, 14, + 19, 8, 21, 66, 67, 12, 69, 33, 34, 64, + 66, 67, 14, 70, 33, 8, 35, 5, 37, 5, + 8, 5, 8, 5, 8, 5, 8, 12, 8, 5, + 49, 50, 8, 33, 34, 78, 79, 16, 12, 47, + 73, 70, 73, 58, 12, 14, 61, 62, 63, 64, + 65, 8, 73, 139, 74, 169, 142, 143, 14, 61, + 62, 63, 64, 65, 150, 151, 152, 12, -1, 47, + -1, 157, -1, -1, -1, 44, -1, 46, -1, 98, + 99, -1, -1, 169, -1, -1, -1, 173, 57, 58, + 46, 177, 61, 62, 63, 64, 65, -1, -1, -1, + 139, -1, 58, 142, 143, 61, 62, 63, 64, 65, + -1, 150, 151, 152, -1, -1, -1, -1, 157, -1, + -1, -1, -1, 1, -1, 3, 145, 5, 6, 7, + 8, 9, -1, -1, 173, -1, -1, 15, 177, 17, + 159, 19, 20, 21, 22, 164, -1, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, 15, -1, 17, + -1, 19, 20, 21, 22, -1, -1, 45, -1, 47, + -1, 49, -1, -1, -1, 53, 54, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 64, 45, 66, 47, + 68, 49, 14, 71, 72, 53, 54, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 64, -1, -1, -1, + 68, -1, -1, 71, 72, 5, 6, 7, 8, 9, + -1, -1, 44, -1, 46, 15, -1, 17, -1, 19, + 20, 21, 22, 55, 56, 57, 58, -1, -1, 61, + 62, 63, 64, 65, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 45, -1, 47, -1, 49, + -1, -1, -1, 53, 54, -1, -1, -1, -1, -1, + -1, -1, -1, 11, 64, 13, 14, -1, 68, -1, + -1, 71, 72, -1, -1, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 44, -1, 46, -1, + -1, 49, -1, -1, -1, 53, 54, 55, 56, 57, + 58, 14, -1, 61, 62, 63, 64, 65, -1, -1, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 44, -1, 46, -1, -1, 49, -1, -1, -1, 53, - 54, 55, 56, 57, 58, 14, -1, 61, 62, 63, - 64, 65, -1, -1, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 44, -1, 46, -1, -1, + -1, 44, -1, 46, -1, -1, 49, -1, -1, -1, + 53, 54, 55, 56, 57, 58, 14, -1, 61, 62, + 63, 64, 65, -1, -1, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 44, -1, 46, -1, + -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, + 58, 14, -1, 61, 62, 63, 64, 65, -1, -1, + 23, 24, 25, 26, 27, 28, 29, -1, 31, -1, + -1, -1, -1, -1, -1, 14, -1, -1, -1, -1, + -1, 44, -1, 46, 23, 24, 25, 26, 27, 28, + 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, + 63, 64, 65, -1, -1, 44, -1, 46, -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, 58, 14, -1, 61, 62, 63, 64, 65, -1, -1, 23, - 24, 25, 26, 27, 28, 29, -1, 31, -1, -1, - -1, -1, -1, -1, 14, -1, -1, -1, -1, -1, - 44, -1, 46, 23, 24, 25, 26, 27, 28, 53, + 24, 25, 26, 27, 28, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 44, -1, 46, -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, 63, - 64, 65, -1, -1, 44, -1, 46, -1, -1, -1, - -1, -1, -1, 53, 54, 55, 56, 57, 58, 14, - -1, 61, 62, 63, 64, 65, -1, -1, 23, 24, - 25, 26, 27, 28, -1, -1, -1, -1, -1, -1, - -1, 14, -1, -1, -1, -1, -1, -1, -1, 44, - -1, 46, -1, -1, -1, -1, -1, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, 44, -1, 46, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 57, 58, -1, -1, 61, 62, - 63, 64, 65 + 64, 65 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of @@ -1393,11 +1349,11 @@ 69, 86, 77, 77, 79, 79, 5, 7, 8, 78, 84, 85, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 5, 8, 5, 8, 84, 84, 12, 70, - 74, 16, 47, 70, 18, 70, 77, 77, 70, 12, - 12, 12, 73, 87, 70, 73, 78, 87, 8, 78, - 78, 77, 87, 78, 78, 78, 73, 74, 77, 12, - 70, 77, 85, 78 + 79, 79, 5, 8, 5, 8, 84, 84, 8, 12, + 70, 74, 16, 47, 70, 18, 70, 77, 77, 70, + 12, 12, 12, 73, 87, 70, 73, 12, 78, 87, + 8, 78, 78, 77, 87, 78, 78, 78, 73, 74, + 78, 77, 8, 12, 70, 77, 85, 12, 78, 78 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ @@ -1412,7 +1368,7 @@ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 81, 82, 83, 83, 83, 83, 83, 83, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 86, - 86, 86, 86, 86, 87 + 86, 86, 86, 86, 86, 86, 86, 86, 87 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ @@ -1427,7 +1383,7 @@ 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 5, 0, 1, 3, 2, 3, 2, 1, 4, 0, 1, 2, 3, 2, 3, 2, 3, 0, - 1, 3, 3, 5, 0 + 1, 3, 2, 4, 3, 5, 4, 6, 0 }; @@ -2634,15 +2590,31 @@ { yyval = xxfirstformal1(yyvsp[-2],yyvsp[0]); modif_token( &(yylsp[-2]), SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ; } break; - case 92: /* formlist: formlist ',' SYMBOL */ + case 92: /* formlist: SYMBOL SYMBOL */ + { yyval = xxfirstformal2(yyvsp[0],yyvsp[-1]); modif_token( &(yylsp[0]), SYMBOL_FORMALS ) ; } + break; + + case 93: /* formlist: SYMBOL SYMBOL EQ_ASSIGN expr_or_help */ + { yyval = xxfirstformal3(yyvsp[-2],yyvsp[0],yyvsp[-3]); modif_token( &(yylsp[-2]), SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ; } + break; + + case 94: /* formlist: formlist ',' SYMBOL */ { yyval = xxaddformal0(yyvsp[-2],yyvsp[0], &(yylsp[0])); modif_token( &(yylsp[0]), SYMBOL_FORMALS ) ; } break; - case 93: /* formlist: formlist ',' SYMBOL EQ_ASSIGN expr_or_help */ - { yyval = xxaddformal1(yyvsp[-4],yyvsp[-2],yyvsp[0],&(yylsp[-2])); modif_token( &(yylsp[-2]), SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ;} + case 95: /* formlist: formlist ',' SYMBOL EQ_ASSIGN expr_or_help */ + { yyval = xxaddformal1(yyvsp[-4],yyvsp[-2],yyvsp[0],&(yylsp[-2])); modif_token( &(yylsp[-2]), SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ; } break; - case 94: /* cr: %empty */ + case 96: /* formlist: formlist ',' SYMBOL SYMBOL */ + { yyval = xxaddformal2(yyvsp[-3],yyvsp[0],yyvsp[-1],&(yylsp[-1])); modif_token( &(yylsp[0]), SYMBOL_FORMALS ) ; } + break; + + case 97: /* formlist: formlist ',' SYMBOL SYMBOL EQ_ASSIGN expr_or_help */ + { yyval = xxaddformal3(yyvsp[-5],yyvsp[-2],yyvsp[0],yyvsp[-3],&(yylsp[-3])); modif_token( &(yylsp[-2]), SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ; } + break; + + case 98: /* cr: %empty */ { EatLines = 1; } break; @@ -3157,6 +3129,31 @@ return ans; } +static SEXP xxfirstformal2(SEXP sym, SEXP type) +{ + SEXP ans; + if (GenerateCode) + PRESERVE_SV(ans = FirstArgWithType(R_MissingArg, sym, type)); + else + PRESERVE_SV(ans = R_NilValue); + RELEASE_SV(type); + RELEASE_SV(sym); + return ans; +} + +static SEXP xxfirstformal3(SEXP sym, SEXP expr, SEXP type) +{ + SEXP ans; + if (GenerateCode) + PRESERVE_SV(ans = FirstArgWithType(expr, sym, type)); + else + PRESERVE_SV(ans = R_NilValue); + RELEASE_SV(type); + RELEASE_SV(expr); + RELEASE_SV(sym); + return ans; +} + static SEXP xxaddformal0(SEXP formlist, SEXP sym, YYLTYPE *lloc) { SEXP ans; @@ -3188,6 +3185,39 @@ return ans; } +static SEXP xxaddformal2(SEXP formlist, SEXP sym, SEXP type, YYLTYPE *lloc) +{ + SEXP ans; + if (GenerateCode) { + CheckFormalArgs(formlist, sym, lloc); + NextArgWithType(formlist, R_MissingArg, sym, type); + ans = formlist; + } else { + RELEASE_SV(formlist); + PRESERVE_SV(ans = R_NilValue); + } + RELEASE_SV(sym); + RELEASE_SV(type); + return ans; +} + +static SEXP xxaddformal3(SEXP formlist, SEXP sym, SEXP expr, SEXP type, YYLTYPE *lloc) +{ + SEXP ans; + if (GenerateCode) { + CheckFormalArgs(formlist, sym, lloc); + NextArgWithType(formlist, expr, sym, type); + ans = formlist; + } else { + RELEASE_SV(formlist); + PRESERVE_SV(ans = R_NilValue); + } + RELEASE_SV(expr); + RELEASE_SV(sym); + RELEASE_SV(type); + return ans; +} + static SEXP xxexprlist0(void) { SEXP ans; @@ -3473,6 +3503,40 @@ return t; } +/* originally, the idea was to use attribute on each entry, but + attrs are only allowed on the outside of LISTSXP so we collect them + into one attribute so they can be used in plain R */ +static SEXP fixupFormalsTypes(SEXP formals) { + SEXP c = CDR(formals); + int i = 0, xty = 0; /* find last type declaration */ + while (c != R_NilValue) { + i++; + /* for speed we don't check the name */ + if (ATTRIB(c) != R_NilValue) + xty = i; + c = CDR(c); + } + if (xty > 0) { + SEXP types = PROTECT(Rf_allocVector(VECSXP, i)); + c = CDR(formals); + i = 0; + while (c != R_NilValue) { + SEXP a = GET_ARGTYPE(c); + if (a != R_NilValue) { + + SET_VECTOR_ELT(types, i, a); + /* do we want to keep them? */ + SET_ATTRIB(c, R_NilValue); + } + c = CDR(c); + i++; + } + SET_ARGTYPE(CDR(formals), types); + UNPROTECT(1); + } + return formals; +} + static SEXP xxdefun(SEXP fname, SEXP formals, SEXP body, YYLTYPE *lloc) { SEXP ans, srcref; @@ -3483,7 +3547,7 @@ ParseState.didAttach = true; } else srcref = R_NilValue; - PRESERVE_SV(ans = lang4(fname, CDR(formals), body, srcref)); + PRESERVE_SV(ans = lang4(fname, CDR(fixupFormalsTypes(formals)), body, srcref)); } else PRESERVE_SV(ans = R_NilValue); RELEASE_SV(body); @@ -3760,6 +3824,17 @@ return tmp; } +static SEXP FirstArgWithType(SEXP s, SEXP tag, SEXP type) +{ + SEXP tmp; + PROTECT(tmp = NewList()); + GrowList(tmp, s); + SET_TAG(CAR(tmp), tag); + SET_ARGTYPE(CAR(tmp), type); + UNPROTECT(1); + return tmp; +} + /* Add named element to the end of a stretchy list */ static void NextArg(SEXP l, SEXP s, SEXP tag) { @@ -3767,6 +3842,13 @@ SET_TAG(CAR(l), tag); } +static void NextArgWithType(SEXP l, SEXP s, SEXP tag, SEXP type) +{ + GrowList(l, s); + SET_TAG(CAR(l), tag); + SET_ARGTYPE(CAR(l), type); +} + /* SrcRefs (PS_SRCREFS) are represented as R_NilValue (empty) or by a stretchy list (which includes another representation for empty) for fast append operation. */ Index: src/main/gram.y =================================================================== --- src/main/gram.y (revision 89063) +++ src/main/gram.y (working copy) @@ -173,6 +173,7 @@ static void CheckFormalArgs(SEXP, SEXP, YYLTYPE *); static SEXP FirstArg(SEXP, SEXP); /* create list with one element */ +static SEXP FirstArgWithType(SEXP, SEXP, SEXP); static void GrowList(SEXP, SEXP); /* add element to list end */ static void SetSingleSrcRef(SEXP); @@ -184,6 +185,7 @@ static int KeywordLookup(const char *); static SEXP NewList(void); static void NextArg(SEXP, SEXP, SEXP); /* add named element to list end */ +static void NextArgWithType(SEXP, SEXP, SEXP, SEXP); static SEXP TagArg(SEXP, SEXP, YYLTYPE *); static int processLineDirective(int *); static bool checkForPlaceholder(SEXP placeholder, SEXP arg); @@ -359,8 +361,12 @@ static SEXP xxnullformal(void); static SEXP xxfirstformal0(SEXP); static SEXP xxfirstformal1(SEXP, SEXP); +static SEXP xxfirstformal2(SEXP, SEXP); +static SEXP xxfirstformal3(SEXP, SEXP, SEXP); static SEXP xxaddformal0(SEXP, SEXP, YYLTYPE *); static SEXP xxaddformal1(SEXP, SEXP, SEXP, YYLTYPE *); +static SEXP xxaddformal2(SEXP, SEXP, SEXP, YYLTYPE *); +static SEXP xxaddformal3(SEXP, SEXP, SEXP, SEXP, YYLTYPE *); static SEXP xxexprlist0(void); static SEXP xxexprlist1(SEXP, YYLTYPE *); static SEXP xxexprlist2(SEXP, SEXP, YYLTYPE *); @@ -559,9 +565,14 @@ formlist: { $$ = xxnullformal(); } | SYMBOL { $$ = xxfirstformal0($1); modif_token( &@1, SYMBOL_FORMALS ) ; } | SYMBOL EQ_ASSIGN expr_or_help { $$ = xxfirstformal1($1,$3); modif_token( &@1, SYMBOL_FORMALS ) ; modif_token( &@2, EQ_FORMALS ) ; } + | SYMBOL SYMBOL { $$ = xxfirstformal2($2,$1); modif_token( &@2, SYMBOL_FORMALS ) ; } + | SYMBOL SYMBOL EQ_ASSIGN expr_or_help + { $$ = xxfirstformal3($2,$4,$1); modif_token( &@2, SYMBOL_FORMALS ) ; modif_token( &@3, EQ_FORMALS ) ; } | formlist ',' SYMBOL { $$ = xxaddformal0($1,$3, &@3); modif_token( &@3, SYMBOL_FORMALS ) ; } | formlist ',' SYMBOL EQ_ASSIGN expr_or_help - { $$ = xxaddformal1($1,$3,$5,&@3); modif_token( &@3, SYMBOL_FORMALS ) ; modif_token( &@4, EQ_FORMALS ) ;} + { $$ = xxaddformal1($1,$3,$5,&@3); modif_token( &@3, SYMBOL_FORMALS ) ; modif_token( &@4, EQ_FORMALS ) ; } + | formlist ',' SYMBOL SYMBOL { $$ = xxaddformal2($1,$4,$3,&@3); modif_token( &@4, SYMBOL_FORMALS ) ; } + | formlist ',' SYMBOL SYMBOL EQ_ASSIGN expr_or_help { $$ = xxaddformal3($1,$4,$6,$3,&@3); modif_token( &@4, SYMBOL_FORMALS ) ; modif_token( &@5, EQ_FORMALS ) ; } ; cr : { EatLines = 1; } @@ -848,6 +859,31 @@ return ans; } +static SEXP xxfirstformal2(SEXP sym, SEXP type) +{ + SEXP ans; + if (GenerateCode) + PRESERVE_SV(ans = FirstArgWithType(R_MissingArg, sym, type)); + else + PRESERVE_SV(ans = R_NilValue); + RELEASE_SV(type); + RELEASE_SV(sym); + return ans; +} + +static SEXP xxfirstformal3(SEXP sym, SEXP expr, SEXP type) +{ + SEXP ans; + if (GenerateCode) + PRESERVE_SV(ans = FirstArgWithType(expr, sym, type)); + else + PRESERVE_SV(ans = R_NilValue); + RELEASE_SV(type); + RELEASE_SV(expr); + RELEASE_SV(sym); + return ans; +} + static SEXP xxaddformal0(SEXP formlist, SEXP sym, YYLTYPE *lloc) { SEXP ans; @@ -879,6 +915,39 @@ return ans; } +static SEXP xxaddformal2(SEXP formlist, SEXP sym, SEXP type, YYLTYPE *lloc) +{ + SEXP ans; + if (GenerateCode) { + CheckFormalArgs(formlist, sym, lloc); + NextArgWithType(formlist, R_MissingArg, sym, type); + ans = formlist; + } else { + RELEASE_SV(formlist); + PRESERVE_SV(ans = R_NilValue); + } + RELEASE_SV(sym); + RELEASE_SV(type); + return ans; +} + +static SEXP xxaddformal3(SEXP formlist, SEXP sym, SEXP expr, SEXP type, YYLTYPE *lloc) +{ + SEXP ans; + if (GenerateCode) { + CheckFormalArgs(formlist, sym, lloc); + NextArgWithType(formlist, expr, sym, type); + ans = formlist; + } else { + RELEASE_SV(formlist); + PRESERVE_SV(ans = R_NilValue); + } + RELEASE_SV(expr); + RELEASE_SV(sym); + RELEASE_SV(type); + return ans; +} + static SEXP xxexprlist0(void) { SEXP ans; @@ -1164,6 +1233,39 @@ return t; } +/* originally, the idea was to use attribute on each entry, but + attrs are only allowed on the outside of LISTSXP so we collect them + into one VECSXP attribute so they can be used in plain R. */ +static SEXP fixupFormalsTypes(SEXP formals) { + SEXP c = CDR(formals); + int i = 0, xty = 0; /* find last type declaration (if any) */ + while (c != R_NilValue) { + i++; + /* for speed we don't check the name */ + if (ATTRIB(c) != R_NilValue) + xty = i; + c = CDR(c); + } + if (xty > 0) { + SEXP types = PROTECT(Rf_allocVector(VECSXP, i)); + c = CDR(formals); + i = 0; + while (c != R_NilValue) { + SEXP a = GET_ARGTYPE(c); + if (a != R_NilValue) { + SET_VECTOR_ELT(types, i, a); + /* do we want to keep them for internal use? */ + SET_ATTRIB(c, R_NilValue); + } + c = CDR(c); + i++; + } + SET_ARGTYPE(CDR(formals), types); + UNPROTECT(1); + } + return formals; +} + static SEXP xxdefun(SEXP fname, SEXP formals, SEXP body, YYLTYPE *lloc) { SEXP ans, srcref; @@ -1174,7 +1276,7 @@ ParseState.didAttach = true; } else srcref = R_NilValue; - PRESERVE_SV(ans = lang4(fname, CDR(formals), body, srcref)); + PRESERVE_SV(ans = lang4(fname, CDR(fixupFormalsTypes(formals)), body, srcref)); } else PRESERVE_SV(ans = R_NilValue); RELEASE_SV(body); @@ -1451,6 +1553,17 @@ return tmp; } +static SEXP FirstArgWithType(SEXP s, SEXP tag, SEXP type) +{ + SEXP tmp; + PROTECT(tmp = NewList()); + GrowList(tmp, s); + SET_TAG(CAR(tmp), tag); + SET_ARGTYPE(CAR(tmp), type); + UNPROTECT(1); + return tmp; +} + /* Add named element to the end of a stretchy list */ static void NextArg(SEXP l, SEXP s, SEXP tag) { @@ -1458,6 +1571,13 @@ SET_TAG(CAR(l), tag); } +static void NextArgWithType(SEXP l, SEXP s, SEXP tag, SEXP type) +{ + GrowList(l, s); + SET_TAG(CAR(l), tag); + SET_ARGTYPE(CAR(l), type); +} + /* SrcRefs (PS_SRCREFS) are represented as R_NilValue (empty) or by a stretchy list (which includes another representation for empty) for fast append operation. */ Index: src/main/names.c =================================================================== --- src/main/names.c (revision 89063) +++ src/main/names.c (working copy) @@ -1132,6 +1132,7 @@ R_SortListSymbol = install("sort.list"); R_SourceSymbol = install("source"); /* Not used by R or core packages */ R_TspSymbol = install("tsp"); + R_TypeSymbol = install("type"); /* ../include/Defn.h , i.e. non-public : */ R_CommentSymbol = install("comment"); R_DotEnvSymbol = install(".Environment"); > On 18/09/2025, at 5:23 AM, IVO I WELCH <[email protected]> wrote: > > > Suggestion for Syntax Sugar: > > Would it make sense to permit a simple way to allow a coder to document the > function argument type? > > f <- function( a:chr, b:data.frame, c:logi ) { … } > > presumably, what comes behind the ‘:’ should match what ‘str’ returns. > > however, this need not be checked (except perhaps when a particular option is > set). catching errors as soon as possible makes code easier to debug and > error messages clearer. > > regards, > > /iaw > > ______________________________________________ > [email protected] mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > ______________________________________________ [email protected] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
