diff --git a/src/language.yacc b/src/language.yacc index 06bab33542b1b41a2ea91c5a73d2401fbf29edfb..f9cd3bd3c786c3e774c5bcae1315db751d3d00d6 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -156,6 +156,7 @@ %token F_XOR_EQ %token F_NOP %token F_UNDEFINED +%token F_OPTIONAL %token F_ALIGN %token F_POINTER @@ -184,7 +185,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.149 1999/12/17 19:47:19 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.150 1999/12/17 21:09:48 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -780,6 +781,17 @@ def: modifiers type_or_error optional_stars F_IDENTIFIER push_compiler_frame0 yyerror("Missing ';'."); /* yychar = '}'; */ /* Put the '}' back on the input stream */ } + | modifiers + '{' + { + $<number>$=lex.pragmas; + lex.pragmas|=$1; + } + program + '}' + { + lex.pragmas=$<number>3; + } ; optional_dot_dot_dot: F_DOT_DOT_DOT { $$=1; } @@ -838,6 +850,7 @@ arguments2: new_arg_name { $$ = 1; } modifier: F_NO_MASK { $$ = ID_NOMASK; } | F_FINAL_ID { $$ = ID_NOMASK; } | F_STATIC { $$ = ID_STATIC; } + | F_OPTIONAL { $$ = ID_OPTIONAL; } | F_PRIVATE { $$ = ID_PRIVATE | ID_STATIC; } | F_LOCAL_ID { $$ = ID_INLINE; } | F_PUBLIC { $$ = ID_PUBLIC; } @@ -854,6 +867,7 @@ magic_identifiers1: | F_PUBLIC { $$ = "public"; } | F_PROTECTED { $$ = "protected"; } | F_INLINE { $$ = "inline"; } + | F_OPTIONAL { $$ = "optional"; } ; magic_identifiers2: @@ -895,14 +909,15 @@ magic_identifiers3: | F_TYPEOF { $$ = "typeof"; } ; -magic_identifiers: magic_identifiers1 | magic_identifiers2 | magic_identifiers3 -magic_identifier: magic_identifiers +magic_identifiers: magic_identifiers1 | magic_identifiers2 | magic_identifiers3 ; + +magic_identifier: F_IDENTIFIER + | magic_identifiers { struct pike_string *tmp=make_shared_string($1); $$=mkstrnode(tmp); free_string(tmp); } - | F_IDENTIFIER ; modifiers: modifier_list @@ -2069,7 +2084,6 @@ expr4: string { $$=mknode(F_ARROW,$1,$3); } - | expr4 F_ARROW bad_identifier {} | expr4 F_ARROW error {} ; @@ -2451,6 +2465,8 @@ bad_expr_ident: { yyerror("protected is a reserved word."); } | F_PUBLIC { yyerror("public is a reserved word."); } + | F_OPTIONAL + { yyerror("optional is a reserved word."); } | F_STATIC { yyerror("static is a reserved word."); } | F_FINAL_ID diff --git a/src/lexer.h b/src/lexer.h index dbe93edd7bbb1d7152e57e719506673985c80ae2..c0261b6096abacff106b0a7c0fc47ca494e851fd 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -1,5 +1,5 @@ /* - * $Id: lexer.h,v 1.12 1999/11/23 03:11:08 grubba Exp $ + * $Id: lexer.h,v 1.13 1999/12/17 21:09:49 hubbe Exp $ * * Lexical analyzer template. * Based on lex.c 1.62 @@ -746,6 +746,9 @@ static int low_yylex(YYSTYPE *yylval) case TWO_CHAR('o','b'): if(ISWORD("object")) return F_OBJECT_ID; break; + case TWO_CHAR('o','p'): + if(ISWORD("optional")) return F_OPTIONAL; + break; case TWO_CHAR('p','r'): if(ISWORD("program")) return F_PROGRAM_ID; if(ISWORD("predef")) return F_PREDEF; diff --git a/src/program.c b/src/program.c index 5406e931df59080ddbf814de4aeae251587c3283..e7be63fcc83d259e253e44075e4f6fe8916acd8e 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.186 1999/12/15 19:42:11 hubbe Exp $"); +RCSID("$Id: program.c,v 1.187 1999/12/17 21:09:51 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -3498,6 +3498,8 @@ static int low_implements(struct program *a, struct program *b) if(s == bid->name) continue; /* Skip __INIT */ i = find_shared_string_identifier(bid->name,a); if (i == -1) { + if (b->identifier_references[e].id_flags & (ID_OPTIONAL)) + continue; /* It's ok... */ #if 0 fprintf(stderr, "Missing identifier \"%s\"\n", bid->name->str); #endif /* 0 */ @@ -3559,6 +3561,8 @@ int yyexplain_not_implements(struct program *a, struct program *b) if(s == bid->name) continue; /* Skip __INIT */ i = find_shared_string_identifier(bid->name,a); if (i == -1) { + if (b->identifier_references[e].id_flags & (ID_OPTIONAL)) + continue; /* It's ok... */ my_yyerror("Missing identifier \"%s\".", bid->name->str); return 0; } diff --git a/src/program.h b/src/program.h index 908087633a6b02897b6a4b14d25e8adfafe94e4f..75d578c7290e8a651b489827f056244afcf64e82 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.72 1999/12/15 19:42:12 hubbe Exp $ + * $Id: program.h,v 1.73 1999/12/17 21:09:52 hubbe Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -162,8 +162,9 @@ struct program_constant #define ID_INLINE 0x20 #define ID_HIDDEN 0x40 /* needed? */ #define ID_INHERITED 0x80 +#define ID_OPTIONAL 0x100 -#define ID_MODIFIER_MASK 0x00ff +#define ID_MODIFIER_MASK 0x01ff #define ID_STRICT_TYPES 0x8000 diff --git a/src/testsuite.in b/src/testsuite.in index 6dd5480e86a48384a0243e3a4401058320002f4a..4dc5d24a04c0ec6f0cdda975558ea750af62df2b 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -test_true([["$Id: testsuite.in,v 1.253 1999/12/14 12:58:19 hubbe Exp $"]]); +test_true([["$Id: testsuite.in,v 1.254 1999/12/17 21:09:53 hubbe Exp $"]]); cond([[all_constants()->_verify_internals]], [[ @@ -847,9 +847,12 @@ test_true(clone(class c { constant i=1; })->i) test_true(clone(class c { constant i=0; mixed `->(string s) { if(s=="i") return 1; }})->i) test_true(clone(class c { constant i=1; mixed `->(string s) { return 0; }})["i"]) test_true(clone(class c { constant i=0; mixed `[](string s) { if(s=="i") return 1; }})["i"]) +test_true(clone(class c { optional constant i=0; mixed `[](string s) { if(s=="i") return 1; }})["i"]) test_true(clone(class c { mixed `[]=(mixed a, mixed b) { if(a!=b) throw(1); }})[1]=1) test_true(clone(class c { mixed `->=(mixed a, mixed b) { if(a!=b) throw(1); }})->i="i") +test_eq((["static":42])->static,42) + test_compile_any(class A {}; class B { inherit A; }) test_any_equal(array a = ({({1,0,0}),({1,1,0}),({0,1,1})}); return map(a,`[],1);, @@ -4165,8 +4168,8 @@ test_compile_any(class A {int v;} class B {inherit A; int v;}) test_compile_error_low(class A {int v;} class B {inherit A; float v;}) test_compile_error_low(class A {int v;} class B {inherit A; mixed v;}) test_compile_error_low(class A {mixed v;} class B {inherit A; int v;}) -test_compile_error_low(class A {public int v;} class B {inherit A; float v;}) test_compile_error_low(class A {public int v;} class B {inherit A; mixed v;}) +test_compile_error_low(class A { public { int v; } } class B {inherit A; mixed v;}) test_compile_error_low(class A {public mixed v;} class B {inherit A; int v;}) test_compile_error_low(class A {static int v;} class B {inherit A; float v;}) test_compile_error_low(class A {static int v;} class B {inherit A; mixed v;})