| 1 |
%{ |
| 2 |
|
| 3 |
#include <stdio.h> |
| 4 |
#include <stdlib.h> |
| 5 |
#include <string.h> |
| 6 |
#include <ctype.h> |
| 7 |
#include "caraway.h" |
| 8 |
#include "node.h" |
| 9 |
|
| 10 |
#define NO_INDENT 0 |
| 11 |
#define CLASS_INDENT 1 |
| 12 |
#define PATTERN_INDENT 2 |
| 13 |
#define METHOD_INDENT 3 |
| 14 |
#define INCINDENT do { indentlv++; preindent = -1; } while (0) |
| 15 |
#define DECINDENT do { indentlv--; preindent = -1; } while (0) |
| 16 |
|
| 17 |
|
| 18 |
static int cldesc; |
| 19 |
static int indentlv; |
| 20 |
static int current_indent; |
| 21 |
static int preindent; |
| 22 |
static int in_def; |
| 23 |
static int next_indent; |
| 24 |
static int next_list_end; |
| 25 |
static int next_pattern; |
| 26 |
static int next_pattern_end; |
| 27 |
static int next_class_end; |
| 28 |
static int indent_stack[3]; |
| 29 |
|
| 30 |
#define IS_NO_LV (indentlv == NO_INDENT) |
| 31 |
#define IS_CLASS_LV (indentlv == CLASS_INDENT) |
| 32 |
#define IS_PATTERN_LV (indentlv == PATTERN_INDENT) |
| 33 |
#define IS_METHOD_LV (indentlv == METHOD_INDENT) |
| 34 |
#define HAS_PREINDENT (preindent > 0) |
| 35 |
|
| 36 |
#define class_indent_size indent_stack[0] |
| 37 |
#define pattern_indent_size indent_stack[1] |
| 38 |
#define method_indent_size indent_stack[2] |
| 39 |
|
| 40 |
static tree_node make_expr_node( node_type nodeType, |
| 41 |
tree_node receiver, |
| 42 |
OOP selector, |
| 43 |
tree_node expression ); |
| 44 |
static tree_node make_tree_node( node_type nodeType ); |
| 45 |
static tree_node make_symbol( char *sval ); |
| 46 |
static tree_node make_char( char cval ); |
| 47 |
static tree_node make_string( char *sval ); |
| 48 |
static tree_node make_int( long ival ); |
| 49 |
static tree_node make_large_int( char *sval ); |
| 50 |
static tree_node make_float( double fval ); |
| 51 |
static tree_node make_decimal( char *sval ); |
| 52 |
static tree_node make_data( char *sval ); |
| 53 |
static tree_node make_uri( char *sval ); |
| 54 |
static tree_node make_binding( tree_node variables ); |
| 55 |
|
| 56 |
static tree_node make_array( tree_node aval ); |
| 57 |
static tree_node make_array_elt( tree_node elt ); |
| 58 |
static tree_node make_dynamic_array( tree_node statements ); |
| 59 |
static tree_node make_variable( char *name ); |
| 60 |
static tree_node make_pseudo_variable( int pseudoType ); |
| 61 |
|
| 62 |
static tree_node make_assign( tree_node variables, |
| 63 |
tree_node expression ); |
| 64 |
static tree_node make_assignment_list( tree_node variable ); |
| 65 |
static tree_node make_return( tree_node expression ); |
| 66 |
static tree_node make_keyword_expr( tree_node receiver, |
| 67 |
tree_node keywordMessage ); |
| 68 |
static tree_node make_keyword_list( char *keyword, |
| 69 |
tree_node expression ); |
| 70 |
static tree_node make_statement_list( tree_node expression ); |
| 71 |
static tree_node make_unary_expr( tree_node receiver, |
| 72 |
char *unarySelectorExpr ); |
| 73 |
static tree_node make_binary_expr( tree_node receiver, |
| 74 |
char *binaryOp, |
| 75 |
tree_node argument ); |
| 76 |
static tree_node make_cascaded_message( tree_node messageExpr, |
| 77 |
tree_node cascadedMessages ); |
| 78 |
static tree_node make_block( tree_node arguments, |
| 79 |
tree_node temporaries, |
| 80 |
tree_node statements ); |
| 81 |
static tree_node make_message_list( tree_node messageElt ); |
| 82 |
|
| 83 |
static tree_node make_variable_list( tree_node variable ); |
| 84 |
static tree_node make_list_node( node_type nodeType, |
| 85 |
char *name, |
| 86 |
tree_node value ); |
| 87 |
static void add_node( tree_node n1, tree_node n2 ); |
| 88 |
|
| 89 |
%} |
| 90 |
|
| 91 |
/* definition of YYSTYPE */ |
| 92 |
%union{ |
| 93 |
char cval; |
| 94 |
double fval; |
| 95 |
long ival; |
| 96 |
char *sval; |
| 97 |
OOP oval; |
| 98 |
tree_node node; |
| 99 |
} |
| 100 |
|
| 101 |
/* single definite characters */ |
| 102 |
%token PRIMITIVE_START "<primitive: ...>" |
| 103 |
%token INTERNAL_TOKEN |
| 104 |
%token SCOPE_SEPARATOR "'.' or '::'" |
| 105 |
%token ASSIGNMENT "'_' or ':='" |
| 106 |
|
| 107 |
/* larger lexical items */ |
| 108 |
%token <sval> IDENTIFIER |
| 109 |
%token <sval> KEYWORD |
| 110 |
%token <sval> INHERIT_KEYWORD |
| 111 |
%token <sval> CATEGORY_KEYWORD |
| 112 |
%token <sval> FIELDS_KEYWORD |
| 113 |
%token <sval> INST_VARS_KEYWORD |
| 114 |
%token <sval> CLASS_VARS_KEYWORD |
| 115 |
%token <sval> INST_METHODS_KEYWORD |
| 116 |
%token <sval> CLASS_METHODS_KEYWORD |
| 117 |
%token <sval> SHARED_VARS_KEYWORD |
| 118 |
%token <sval> TIMESTAMP_KEYWORD |
| 119 |
%token <sval> STRING_LITERAL |
| 120 |
%token <sval> SYMBOL_KEYWORD |
| 121 |
%token <sval> BINOP |
| 122 |
%token <sval> '|' |
| 123 |
%token <ival> INTEGER_LITERAL |
| 124 |
%token <sval> HEX_STRING |
| 125 |
%token <sval> LARGE_INTEGER_LITERAL |
| 126 |
%token <fval> FLOAT_LITERAL |
| 127 |
%token <cval> CHAR_LITERAL |
| 128 |
%token <sval> DECIMAL_LITERAL |
| 129 |
%token <sval> URI |
| 130 |
%token METHOD_END |
| 131 |
%token METHOD_LIST_END |
| 132 |
%token CLASS_START |
| 133 |
%token MODULE_START |
| 134 |
%token CLASS_END |
| 135 |
%token MESSAGE_PATTERN_END |
| 136 |
%token TERMINATE |
| 137 |
%token DATA_START |
| 138 |
%token TRUE |
| 139 |
%token FALSE |
| 140 |
%token NIL |
| 141 |
%token SELF |
| 142 |
%token SUPER |
| 143 |
%token THIS_CONTEXT |
| 144 |
// <boval> |
| 145 |
%type <node> method message_pattern variable_name keyword_variable_list |
| 146 |
temporaries variable_names statements |
| 147 |
statements.1 statement expression return_statement assigns |
| 148 |
primary number symbol uri character string dictionary data |
| 149 |
array array_body array_list array_elt |
| 150 |
dynamic_array dynamic_array dynamic_array_list |
| 151 |
block opt_block_variables block_variable_list |
| 152 |
unary_expression binary_expression |
| 153 |
keyword_expression keyword_binary_object_description_list |
| 154 |
cascaded_message_expression semi_message_list |
| 155 |
message_elt simple_expression message_expression |
| 156 |
unary_object_description |
| 157 |
binary_object_description |
| 158 |
pseudo_variables literal dynamic_literal static_literal |
| 159 |
variable_binding variable_primary |
| 160 |
%type <sval> unary_selector keyword reserved_keyword binary_selector |
| 161 |
primitive symbol_body |
| 162 |
%% |
| 163 |
|
| 164 |
program |
| 165 |
: file_in_list |
| 166 |
; |
| 167 |
|
| 168 |
file_in_list |
| 169 |
: file_in_list file_in |
| 170 |
| /* empty */ |
| 171 |
; |
| 172 |
|
| 173 |
file_in |
| 174 |
: doit |
| 175 |
| class_module_declaration |
| 176 |
; |
| 177 |
|
| 178 |
doit |
| 179 |
: temporaries |
| 180 |
{ |
| 181 |
in_def = 1; |
| 182 |
} |
| 183 |
terminate toplevel_statements |
| 184 |
; |
| 185 |
|
| 186 |
toplevel_statements |
| 187 |
: toplevel_statements statement '.' |
| 188 |
| /* empty */ |
| 189 |
; |
| 190 |
|
| 191 |
class_module_declaration |
| 192 |
: class_module_start class_name |
| 193 |
{ |
| 194 |
printf("=== class module declaration start ===\n"); |
| 195 |
cldesc = 1; |
| 196 |
INCINDENT; |
| 197 |
class_indent_size = -1; |
| 198 |
pattern_indent_size = -1; |
| 199 |
method_indent_size = -1; |
| 200 |
in_def = 1; |
| 201 |
} |
| 202 |
subclass terminate class_description |
| 203 |
{ |
| 204 |
cldesc = 0; |
| 205 |
} |
| 206 |
attr_declarations class_end |
| 207 |
; |
| 208 |
|
| 209 |
class_end |
| 210 |
: CLASS_END |
| 211 |
{ |
| 212 |
printf("=== class end ===\n"); |
| 213 |
DECINDENT; |
| 214 |
} |
| 215 |
; |
| 216 |
|
| 217 |
class_module_start |
| 218 |
: CLASS_START |
| 219 |
| MODULE_START |
| 220 |
; |
| 221 |
|
| 222 |
class_name |
| 223 |
: IDENTIFIER |
| 224 |
; |
| 225 |
|
| 226 |
subclass |
| 227 |
: ':' class_name |
| 228 |
| /* empty */ |
| 229 |
; |
| 230 |
|
| 231 |
terminate |
| 232 |
: TERMINATE |
| 233 |
; |
| 234 |
|
| 235 |
class_description |
| 236 |
: string |
| 237 |
{ |
| 238 |
printf("=== comment ===\n"); |
| 239 |
in_def = 1; |
| 240 |
} |
| 241 |
terminate |
| 242 |
| /* empty */ |
| 243 |
; |
| 244 |
|
| 245 |
attr_declarations |
| 246 |
: attr_declarations |
| 247 |
{ |
| 248 |
printf("=== attr declaration start ===\n"); |
| 249 |
in_def = 1; |
| 250 |
} |
| 251 |
attr_declaration |
| 252 |
{ |
| 253 |
if (class_indent_size < 0) |
| 254 |
class_indent_size = current_indent; |
| 255 |
} |
| 256 |
terminate |
| 257 |
| terminate |
| 258 |
| /* empty */ |
| 259 |
; |
| 260 |
|
| 261 |
attr_declaration |
| 262 |
: category |
| 263 |
| instance_variables |
| 264 |
| class_instance_variables |
| 265 |
| instance_method_list |
| 266 |
| class_method_list |
| 267 |
| shared_variable_list |
| 268 |
; |
| 269 |
|
| 270 |
category |
| 271 |
: CATEGORY_KEYWORD string |
| 272 |
; |
| 273 |
|
| 274 |
instance_variables |
| 275 |
: INST_VARS_KEYWORD string |
| 276 |
; |
| 277 |
|
| 278 |
class_instance_variables |
| 279 |
: CLASS_VARS_KEYWORD string |
| 280 |
; |
| 281 |
|
| 282 |
instance_method_list |
| 283 |
: INST_METHODS_KEYWORD generic_method_list |
| 284 |
; |
| 285 |
|
| 286 |
class_method_list |
| 287 |
: CLASS_METHODS_KEYWORD generic_method_list |
| 288 |
; |
| 289 |
|
| 290 |
generic_method_list |
| 291 |
: method_category |
| 292 |
{ |
| 293 |
printf("=== method list start ===\n"); |
| 294 |
next_list_end = 0; |
| 295 |
INCINDENT; |
| 296 |
next_pattern = 0; |
| 297 |
} |
| 298 |
terminate |
| 299 |
method_list method_list_end |
| 300 |
; |
| 301 |
|
| 302 |
method_category |
| 303 |
: string |
| 304 |
| /* empty */ |
| 305 |
; |
| 306 |
|
| 307 |
method_list |
| 308 |
: method |
| 309 |
| method_list method |
| 310 |
; |
| 311 |
|
| 312 |
method_list_end |
| 313 |
: METHOD_LIST_END |
| 314 |
{ |
| 315 |
printf("=== method list end ===\n"); |
| 316 |
DECINDENT; |
| 317 |
} |
| 318 |
; |
| 319 |
|
| 320 |
method |
| 321 |
: message_pattern message_pattern_end |
| 322 |
temporaries primitive statements method_end |
| 323 |
; |
| 324 |
|
| 325 |
method_end |
| 326 |
: METHOD_END |
| 327 |
{ |
| 328 |
DECINDENT; |
| 329 |
printf("=== method end ===\n"); |
| 330 |
} |
| 331 |
; |
| 332 |
|
| 333 |
message_pattern |
| 334 |
: unary_selector |
| 335 |
{ |
| 336 |
$$ = make_unary_expr(NULL, $1); |
| 337 |
} |
| 338 |
| binary_selector variable_name |
| 339 |
{ |
| 340 |
$$ = make_binary_expr(NULL, $1, $2); |
| 341 |
} |
| 342 |
| keyword_variable_list |
| 343 |
{ |
| 344 |
$$ = make_keyword_expr(NULL, $1); |
| 345 |
} |
| 346 |
; |
| 347 |
|
| 348 |
|
| 349 |
message_pattern_end |
| 350 |
: MESSAGE_PATTERN_END |
| 351 |
{ |
| 352 |
INCINDENT; |
| 353 |
printf("=== message pattern end ===\n"); |
| 354 |
if (pattern_indent_size < 0) |
| 355 |
pattern_indent_size = current_indent; |
| 356 |
} |
| 357 |
; |
| 358 |
|
| 359 |
shared_variable_list |
| 360 |
: SHARED_VARS_KEYWORD method_category |
| 361 |
{ |
| 362 |
printf("=== shared variable list start ===\n"); |
| 363 |
next_list_end = 0; |
| 364 |
INCINDENT; |
| 365 |
next_pattern = 0; |
| 366 |
} |
| 367 |
terminate shared_variable_list_body shared_variable_list_body_end |
| 368 |
; |
| 369 |
|
| 370 |
shared_variable_list_body |
| 371 |
: shared_variable |
| 372 |
| shared_variable_list_body shared_variable |
| 373 |
; |
| 374 |
|
| 375 |
shared_variable_list_body_end |
| 376 |
: METHOD_LIST_END |
| 377 |
{ |
| 378 |
printf("=== shared variable lisst body end ===\n"); |
| 379 |
DECINDENT; |
| 380 |
} |
| 381 |
; |
| 382 |
|
| 383 |
shared_variable |
| 384 |
: variable_name shared_variable_pattern_end |
| 385 |
statements method_end |
| 386 |
; |
| 387 |
|
| 388 |
shared_variable_pattern_end |
| 389 |
: MESSAGE_PATTERN_END |
| 390 |
{ |
| 391 |
INCINDENT; |
| 392 |
printf("=== shared variable pattern end ===\n"); |
| 393 |
if (pattern_indent_size < 0) |
| 394 |
pattern_indent_size = current_indent; |
| 395 |
} |
| 396 |
; |
| 397 |
|
| 398 |
|
| 399 |
unary_selector |
| 400 |
: IDENTIFIER |
| 401 |
; |
| 402 |
|
| 403 |
binary_selector |
| 404 |
: BINOP |
| 405 |
| '|' |
| 406 |
; |
| 407 |
|
| 408 |
variable_name |
| 409 |
: IDENTIFIER |
| 410 |
{ |
| 411 |
$$ = make_variable($1); |
| 412 |
} |
| 413 |
; |
| 414 |
|
| 415 |
keyword_variable_list |
| 416 |
: keyword variable_name |
| 417 |
{ |
| 418 |
$$ = make_keyword_list($1, $2); |
| 419 |
} |
| 420 |
| keyword_variable_list keyword variable_name |
| 421 |
{ |
| 422 |
add_node($1, make_keyword_list($2, $3)); |
| 423 |
$$ = $1; |
| 424 |
} |
| 425 |
; |
| 426 |
|
| 427 |
optional_terminate |
| 428 |
: terminate |
| 429 |
| /* empty */ |
| 430 |
; |
| 431 |
|
| 432 |
keyword |
| 433 |
: KEYWORD |
| 434 |
| reserved_keyword |
| 435 |
; |
| 436 |
|
| 437 |
reserved_keyword |
| 438 |
: INHERIT_KEYWORD |
| 439 |
| CATEGORY_KEYWORD |
| 440 |
| TIMESTAMP_KEYWORD |
| 441 |
| FIELDS_KEYWORD |
| 442 |
| INST_VARS_KEYWORD |
| 443 |
| CLASS_VARS_KEYWORD |
| 444 |
| INST_METHODS_KEYWORD |
| 445 |
| CLASS_METHODS_KEYWORD |
| 446 |
; |
| 447 |
|
| 448 |
primitive |
| 449 |
: /* empty */ { $$ = 0; } |
| 450 |
| PRIMITIVE_START IDENTIFIER primitive_end { $$ = $2; } |
| 451 |
; |
| 452 |
|
| 453 |
primitive_end |
| 454 |
: BINOP |
| 455 |
{ |
| 456 |
if (strcmp($1, ">") != 0) yyerror("primitive end must be '>'"); |
| 457 |
} |
| 458 |
; |
| 459 |
|
| 460 |
temporaries |
| 461 |
: /* empty */ { $$ = NULL; } |
| 462 |
| '|' '|' { $$ = NULL; } |
| 463 |
| '|' variable_names '|' { $$ = $2; } |
| 464 |
; |
| 465 |
|
| 466 |
variable_names |
| 467 |
: variable_name |
| 468 |
{ |
| 469 |
$$ = make_variable_list($1); |
| 470 |
} |
| 471 |
| variable_names variable_name |
| 472 |
{ |
| 473 |
add_node($1, make_variable_list($2)); |
| 474 |
$$ = $1; |
| 475 |
} |
| 476 |
; |
| 477 |
|
| 478 |
statements |
| 479 |
: /* empty */ { $$ = NULL; } |
| 480 |
| return_statement optional_dot { $$ = $1; } |
| 481 |
| statements.1 optional_dot { $$ = $1; } |
| 482 |
| statements.1 '.' return_statement optional_dot |
| 483 |
{ |
| 484 |
add_node ($1, $3); |
| 485 |
$$ = $1; |
| 486 |
} |
| 487 |
; |
| 488 |
|
| 489 |
statements.1 |
| 490 |
: statement { $$ = $1; } |
| 491 |
| statements.1 '.' statement |
| 492 |
{ |
| 493 |
add_node($1, $3); |
| 494 |
$$ = $1; |
| 495 |
} |
| 496 |
| statements.1 '.' error |
| 497 |
{ |
| 498 |
$$ = $1; |
| 499 |
yyerrok; |
| 500 |
} |
| 501 |
; |
| 502 |
|
| 503 |
optional_dot |
| 504 |
: /* empty */ |
| 505 |
| '.' |
| 506 |
; |
| 507 |
|
| 508 |
statement |
| 509 |
: expression { $$ = make_statement_list($1); } |
| 510 |
; |
| 511 |
|
| 512 |
return_statement |
| 513 |
: '^' expression |
| 514 |
{ |
| 515 |
$$ = make_statement_list(make_return($2)); |
| 516 |
} |
| 517 |
; |
| 518 |
|
| 519 |
expression |
| 520 |
: simple_expression |
| 521 |
| assigns simple_expression { $$ = make_assign($1, $2); } |
| 522 |
; |
| 523 |
|
| 524 |
assigns |
| 525 |
: variable_primary ASSIGNMENT |
| 526 |
{ |
| 527 |
$$ = make_assignment_list($1); |
| 528 |
} |
| 529 |
| assigns variable_primary ASSIGNMENT |
| 530 |
{ |
| 531 |
add_node($1, make_assignment_list($2)); |
| 532 |
$$ = $1; |
| 533 |
} |
| 534 |
; |
| 535 |
|
| 536 |
simple_expression |
| 537 |
: primary |
| 538 |
| message_expression |
| 539 |
| cascaded_message_expression |
| 540 |
; |
| 541 |
|
| 542 |
primary |
| 543 |
: variable_primary |
| 544 |
| literal |
| 545 |
| pseudo_variables |
| 546 |
| '(' error ')' |
| 547 |
{ |
| 548 |
yyerrok; |
| 549 |
$$ = NULL; |
| 550 |
} |
| 551 |
| '(' expression ')' { $$ = $2; } |
| 552 |
; |
| 553 |
|
| 554 |
variable_primary |
| 555 |
: IDENTIFIER |
| 556 |
{ |
| 557 |
$$ = make_variable($1); |
| 558 |
} |
| 559 |
| variable_primary SCOPE_SEPARATOR IDENTIFIER |
| 560 |
{ |
| 561 |
add_node($1, make_variable($3)); |
| 562 |
} |
| 563 |
; |
| 564 |
|
| 565 |
literal |
| 566 |
: static_literal |
| 567 |
| dynamic_literal |
| 568 |
; |
| 569 |
|
| 570 |
static_literal |
| 571 |
: number |
| 572 |
| symbol |
| 573 |
| character |
| 574 |
| string |
| 575 |
| array |
| 576 |
| data |
| 577 |
| uri |
| 578 |
| variable_binding |
| 579 |
; |
| 580 |
|
| 581 |
dynamic_literal |
| 582 |
: dynamic_array |
| 583 |
| dictionary |
| 584 |
| block |
| 585 |
; |
| 586 |
|
| 587 |
number |
| 588 |
: INTEGER_LITERAL { $$ = make_int($1); } |
| 589 |
| FLOAT_LITERAL { $$ = make_float($1); } |
| 590 |
| LARGE_INTEGER_LITERAL { $$ = make_large_int($1); } |
| 591 |
| DECIMAL_LITERAL { $$ = make_decimal($1); } |
| 592 |
; |
| 593 |
|
| 594 |
symbol |
| 595 |
: '#' symbol_body { $$ = make_symbol($2); } |
| 596 |
| '#' STRING_LITERAL { $$ = make_symbol($2); } |
| 597 |
; |
| 598 |
|
| 599 |
symbol_body |
| 600 |
: IDENTIFIER |
| 601 |
| binary_selector |
| 602 |
| SYMBOL_KEYWORD |
| 603 |
| KEYWORD |
| 604 |
; |
| 605 |
|
| 606 |
character |
| 607 |
: CHAR_LITERAL { $$ = make_char($1); } |
| 608 |
; |
| 609 |
|
| 610 |
string |
| 611 |
: STRING_LITERAL { $$ = make_string($1); } |
| 612 |
; |
| 613 |
|
| 614 |
array |
| 615 |
: '#' array_body { $$ = $2; } |
| 616 |
; |
| 617 |
|
| 618 |
array_body |
| 619 |
: '(' ')' { $$ = make_array(NULL); } |
| 620 |
| '(' array_list ')' { $$ = make_array($2); } |
| 621 |
| '(' error ')' |
| 622 |
{ |
| 623 |
yyerrok; |
| 624 |
//_gst_had_error = true; |
| 625 |
$$ = NULL; |
| 626 |
} |
| 627 |
; |
| 628 |
|
| 629 |
array_list |
| 630 |
: array_elt { $$ = make_array_elt($1); } |
| 631 |
| array_list array_elt |
| 632 |
{ |
| 633 |
add_node($1, make_array_elt($2)); |
| 634 |
$$ = $1; |
| 635 |
} |
| 636 |
; |
| 637 |
|
| 638 |
array_elt |
| 639 |
: static_literal |
| 640 |
| pseudo_variables |
| 641 |
; |
| 642 |
|
| 643 |
pseudo_variables |
| 644 |
: TRUE { $$ = make_pseudo_variable(PSEUDO_TRUE); } |
| 645 |
| FALSE { $$ = make_pseudo_variable(PSEUDO_FALSE); } |
| 646 |
| NIL { $$ = make_pseudo_variable(PSEUDO_NIL); } |
| 647 |
| SELF { $$ = make_pseudo_variable(PSEUDO_SELF); } |
| 648 |
| SUPER { $$ = make_pseudo_variable(PSEUDO_SUPER); } |
| 649 |
| THIS_CONTEXT { $$ = make_pseudo_variable(PSEUDO_CONTEXT); } |
| 650 |
; |
| 651 |
|
| 652 |
data |
| 653 |
: DATA_START HEX_STRING |
| 654 |
{ |
| 655 |
$$ = make_data($2); |
| 656 |
in_data = 0; |
| 657 |
} |
| 658 |
; |
| 659 |
|
| 660 |
uri |
| 661 |
: URI { $$ = make_uri($1); } |
| 662 |
; |
| 663 |
|
| 664 |
variable_binding |
| 665 |
: '#' '{' error '}' |
| 666 |
{ |
| 667 |
yyerrok; |
| 668 |
//_gst_had_error = true; |
| 669 |
$$ = NULL; |
| 670 |
} |
| 671 |
| '#' '{' variable_primary '}' |
| 672 |
{ |
| 673 |
$$ = make_binding($3); |
| 674 |
if (!$$) { |
| 675 |
//_gst_errorf ("invalid variable binding"); |
| 676 |
YYERROR; |
| 677 |
} |
| 678 |
} |
| 679 |
; |
| 680 |
|
| 681 |
dynamic_array |
| 682 |
: '{' error '}' |
| 683 |
{ |
| 684 |
yyerrok; |
| 685 |
$$ = NULL; |
| 686 |
} |
| 687 |
| '{' dynamic_array_list '}' { $$ = make_dynamic_array($2); } |
| 688 |
; |
| 689 |
|
| 690 |
dynamic_array_list |
| 691 |
: statement { $$ = $1; } |
| 692 |
| statement ',' dynamic_array_list { add_node($1, $3); } |
| 693 |
; |
| 694 |
|
| 695 |
dictionary |
| 696 |
: '{' ':' '}' { $$ = NULL; } |
| 697 |
| '{' associations '}' { $$ = NULL; } |
| 698 |
; |
| 699 |
|
| 700 |
associations |
| 701 |
: association |
| 702 |
| association ',' associations |
| 703 |
; |
| 704 |
|
| 705 |
association |
| 706 |
: statement ':' statement |
| 707 |
; |
| 708 |
|
| 709 |
block |
| 710 |
: '[' error ']' |
| 711 |
{ |
| 712 |
yyerrok; |
| 713 |
$$ = NULL; |
| 714 |
} |
| 715 |
| '[' opt_block_variables temporaries statements ']' |
| 716 |
{ |
| 717 |
$$ = make_block($2, $3, $4); |
| 718 |
} |
| 719 |
; |
| 720 |
|
| 721 |
opt_block_variables |
| 722 |
: /* empty */ { $$ = NULL; } |
| 723 |
| block_variable_list binary_selector |
| 724 |
{ |
| 725 |
if ($2[0] != '|') { |
| 726 |
yyerror("block variables end must be '|'"); |
| 727 |
} else if ($2[1] == '\0') { /* | */ |
| 728 |
} else if ($2[1] == '|') { /* || */ |
| 729 |
//_gst_unread_char('|'); |
| 730 |
} |
| 731 |
} |
| 732 |
; |
| 733 |
|
| 734 |
block_variable_list |
| 735 |
: ':' variable_name |
| 736 |
{ |
| 737 |
$$ = make_variable_list($2); |
| 738 |
} |
| 739 |
| block_variable_list ':' variable_name |
| 740 |
{ |
| 741 |
add_node($1, make_variable_list($3)); |
| 742 |
$$ = $1; |
| 743 |
} |
| 744 |
; |
| 745 |
|
| 746 |
message_expression |
| 747 |
: unary_expression |
| 748 |
| binary_expression |
| 749 |
| keyword_expression |
| 750 |
; |
| 751 |
|
| 752 |
unary_expression |
| 753 |
: unary_object_description unary_selector |
| 754 |
{ |
| 755 |
$$ = make_unary_expr($1, $2); |
| 756 |
} |
| 757 |
; |
| 758 |
|
| 759 |
unary_object_description |
| 760 |
: primary |
| 761 |
| unary_expression |
| 762 |
; |
| 763 |
|
| 764 |
binary_expression |
| 765 |
: binary_object_description binary_selector unary_object_description |
| 766 |
{ |
| 767 |
$$ = make_binary_expr($1, $2, $3); |
| 768 |
} |
| 769 |
; |
| 770 |
|
| 771 |
binary_object_description |
| 772 |
: unary_object_description |
| 773 |
| binary_expression |
| 774 |
; |
| 775 |
|
| 776 |
keyword_expression |
| 777 |
: binary_object_description keyword_binary_object_description_list |
| 778 |
{ |
| 779 |
$$ = make_keyword_expr($1, $2); |
| 780 |
} |
| 781 |
; |
| 782 |
|
| 783 |
keyword_binary_object_description_list |
| 784 |
: keyword binary_object_description |
| 785 |
{ |
| 786 |
$$ = make_keyword_list($1, $2); |
| 787 |
} |
| 788 |
| keyword_binary_object_description_list keyword |
| 789 |
binary_object_description |
| 790 |
{ |
| 791 |
add_node($1, make_keyword_list($2, $3)); |
| 792 |
$$ = $1; |
| 793 |
} |
| 794 |
; |
| 795 |
|
| 796 |
cascaded_message_expression |
| 797 |
: message_expression semi_message_list |
| 798 |
{ |
| 799 |
$$ = make_cascaded_message($1, $2); |
| 800 |
} |
| 801 |
; |
| 802 |
|
| 803 |
semi_message_list |
| 804 |
: ';' message_elt |
| 805 |
{ |
| 806 |
$$ = make_message_list($2); |
| 807 |
} |
| 808 |
| semi_message_list ';' message_elt |
| 809 |
{ |
| 810 |
add_node($1, make_message_list($3)); |
| 811 |
$$ = $1; |
| 812 |
} |
| 813 |
; |
| 814 |
|
| 815 |
message_elt |
| 816 |
: unary_selector |
| 817 |
{ |
| 818 |
$$ = make_unary_expr(NULL, $1); |
| 819 |
} |
| 820 |
| binary_selector unary_object_description |
| 821 |
{ |
| 822 |
$$ = make_binary_expr(NULL, $1, $2); |
| 823 |
} |
| 824 |
| keyword_binary_object_description_list |
| 825 |
{ |
| 826 |
$$ = make_keyword_expr(NULL, $1); |
| 827 |
} |
| 828 |
; |
| 829 |
|
| 830 |
|
| 831 |
%% |
| 832 |
static char *lex_str = NULL; |
| 833 |
static char *token = NULL; |
| 834 |
static int lex_p; |
| 835 |
static int lex_pend; |
| 836 |
static int token_index; |
| 837 |
static int token_size; |
| 838 |
static int in_data; |
| 839 |
|
| 840 |
#define peek(c) (lex_p != lex_pend && (c) == lex_str[lex_p]) |
| 841 |
#define peekc lex_str[lex_p] |
| 842 |
#define tokencmp(str) (strcmp(token, str) == 0) |
| 843 |
|
| 844 |
static int |
| 845 |
peek_str( const char *str ) |
| 846 |
{ |
| 847 |
int i; |
| 848 |
|
| 849 |
for (i = 0; i < strlen(str); i++) { |
| 850 |
if (peek(str[i])) |
| 851 |
return 1; |
| 852 |
} |
| 853 |
return 0; |
| 854 |
} |
| 855 |
|
| 856 |
static inline int nextc() |
| 857 |
{ |
| 858 |
if (lex_p == lex_pend) |
| 859 |
return -1; |
| 860 |
return lex_str[lex_p++]; |
| 861 |
} |
| 862 |
|
| 863 |
static void |
| 864 |
pushback( int c ) |
| 865 |
{ |
| 866 |
if (c == -1) return; |
| 867 |
lex_p--; |
| 868 |
} |
| 869 |
|
| 870 |
static char *newtoken() |
| 871 |
{ |
| 872 |
token_index = 0; |
| 873 |
if (!token) { |
| 874 |
token_size = 60; |
| 875 |
token = malloc(sizeof(char) * 60); |
| 876 |
} |
| 877 |
if (token_size > 4096) { |
| 878 |
token_size = 60; |
| 879 |
realloc(token, sizeof(char) * 60); |
| 880 |
} |
| 881 |
return token; |
| 882 |
} |
| 883 |
|
| 884 |
static void tokenadd( char c ) |
| 885 |
{ |
| 886 |
token[token_index++] = c; |
| 887 |
if (token_index >= token_size) { |
| 888 |
token_size *= 2; |
| 889 |
token = realloc(token, sizeof(char) * token_size); |
| 890 |
} |
| 891 |
token[token_index] = '\0'; |
| 892 |
} |
| 893 |
|
| 894 |
void setindent( int newsize ) |
| 895 |
{ |
| 896 |
int size; |
| 897 |
|
| 898 |
size = indent_stack[indentlv-1]; |
| 899 |
if (size < 0) |
| 900 |
indent_stack[indentlv-1] = newsize; |
| 901 |
else if (size) { |
| 902 |
} |
| 903 |
} |
| 904 |
|
| 905 |
/* |
| 906 |
* identifier, operator, colon, term, |
| 907 |
* $B%7%s%\%k!"8GDjG[Ns!"J8;z(B |
| 908 |
*/ |
| 909 |
int |
| 910 |
yylex() |
| 911 |
{ |
| 912 |
int c, i, len, isbase = 0, isfloat = 0, isscaled = 0, isexp = 0, returns; |
| 913 |
|
| 914 |
if (next_list_end == 1) { |
| 915 |
next_list_end = 2; |
| 916 |
return METHOD_LIST_END; |
| 917 |
} else if (next_list_end == 2) { |
| 918 |
next_list_end = 0; |
| 919 |
return TERMINATE; |
| 920 |
} |
| 921 |
|
| 922 |
if (in_data) { |
| 923 |
newtoken(); |
| 924 |
while (1) { |
| 925 |
switch (c = nextc()) { |
| 926 |
case '>': |
| 927 |
yylval.sval = token; |
| 928 |
return HEX_STRING; |
| 929 |
|
| 930 |
case '0': case '1': case '2': case '3': case '4': |
| 931 |
case '5': case '6': case '7': case '8': case '9': |
| 932 |
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': |
| 933 |
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': |
| 934 |
tokenadd(c); |
| 935 |
break; |
| 936 |
|
| 937 |
case ' ': case '\r': case '\n': case '\t': |
| 938 |
break; |
| 939 |
|
| 940 |
default: |
| 941 |
printf("* byte error %d\n", c); |
| 942 |
return 0; |
| 943 |
} |
| 944 |
} |
| 945 |
} |
| 946 |
|
| 947 |
while (1) { |
| 948 |
switch (c = nextc()) { |
| 949 |
case '\0': /* NULL */ |
| 950 |
case '\004': /* ^D */ |
| 951 |
case '\032': /* ^Z */ |
| 952 |
return 0; |
| 953 |
|
| 954 |
case -1: /* end of script. */ |
| 955 |
if (indentlv > NO_INDENT) |
| 956 |
return CLASS_END; |
| 957 |
return 0; |
| 958 |
|
| 959 |
/* comment */ |
| 960 |
case '"': |
| 961 |
while (nextc() != '"'); |
| 962 |
nextc(); |
| 963 |
while ((c = nextc()) != '\r' && c != '\n' && c != -1); |
| 964 |
pushback(c); |
| 965 |
break; |
| 966 |
|
| 967 |
/* return */ |
| 968 |
case '\r': case '\n': |
| 969 |
if (indentlv == NO_INDENT) { |
| 970 |
while (peek('\r') || peek('\n')) |
| 971 |
nextc(); |
| 972 |
if (in_def) { |
| 973 |
in_def = 0; |
| 974 |
return TERMINATE; |
| 975 |
} |
| 976 |
break; |
| 977 |
} else if (indentlv > NO_INDENT && !peek('\r') && !peek('\n') && |
| 978 |
!peek(' ')) { |
| 979 |
return CLASS_END; |
| 980 |
} |
| 981 |
if (c == '\r' && peek('\n')) nextc(); |
| 982 |
next_indent = 1; |
| 983 |
if (in_def) { |
| 984 |
in_def = 0; |
| 985 |
printf("terminate = %d\n", indentlv); |
| 986 |
return TERMINATE; |
| 987 |
} else if (IS_PATTERN_LV && next_pattern) { |
| 988 |
next_pattern_end = 1; |
| 989 |
} |
| 990 |
break; |
| 991 |
|
| 992 |
/* white space or indent */ |
| 993 |
case ' ': |
| 994 |
if (!next_indent) { |
| 995 |
while ((c = nextc()) == ' '); |
| 996 |
pushback(c); |
| 997 |
break; |
| 998 |
} |
| 999 |
next_indent = 0; |
| 1000 |
current_indent = 1; |
| 1001 |
while ((c = nextc()) == ' ') |
| 1002 |
current_indent++; |
| 1003 |
pushback(c); |
| 1004 |
if (peek('\r') || peek('\n')) |
| 1005 |
break; |
| 1006 |
setindent(current_indent); |
| 1007 |
printf("* lv:%d [%d %d %d], current = %d, pre = %d\n", indentlv, |
| 1008 |
class_indent_size, pattern_indent_size, method_indent_size, |
| 1009 |
current_indent, preindent); |
| 1010 |
if (next_pattern_end) { |
| 1011 |
if (current_indent == pattern_indent_size) |
| 1012 |
break; |
| 1013 |
else if (current_indent > pattern_indent_size) { |
| 1014 |
next_pattern_end = 0; |
| 1015 |
return MESSAGE_PATTERN_END; |
| 1016 |
} |
| 1017 |
} |
| 1018 |
if (IS_METHOD_LV && current_indent < method_indent_size) { |
| 1019 |
if (current_indent <= class_indent_size) |
| 1020 |
next_list_end = 1; |
| 1021 |
return METHOD_END; |
| 1022 |
} |
| 1023 |
break; |
| 1024 |
|
| 1025 |
/* white spaces */ |
| 1026 |
case '\t': case '\f': case '\13': /* '\v' */ |
| 1027 |
break; |
| 1028 |
|
| 1029 |
/* char */ |
| 1030 |
case '$': |
| 1031 |
newtoken(); |
| 1032 |
if (c = nextc()) { |
| 1033 |
tokenadd(c); |
| 1034 |
yylval.cval = c; |
| 1035 |
return CHAR_LITERAL; |
| 1036 |
} else { |
| 1037 |
printf("* char error\n"); |
| 1038 |
return 0; |
| 1039 |
} |
| 1040 |
|
| 1041 |
/* string */ |
| 1042 |
case '\'': |
| 1043 |
newtoken(); |
| 1044 |
if ((c = nextc()) == '\'' && peek('\'')) { |
| 1045 |
// ''' string ''' |
| 1046 |
nextc(); |
| 1047 |
nextc(); |
| 1048 |
int prec; |
| 1049 |
while ((c = nextc()) != 0) { |
| 1050 |
prec = c; |
| 1051 |
if (c == '\'') { |
| 1052 |
if ((c = nextc()) == '\'' && peek('\'')) { |
| 1053 |
nextc(); |
| 1054 |
printf("* string - %s\n", token); |
| 1055 |
yylval.sval = token; |
| 1056 |
return STRING_LITERAL; |
| 1057 |
} else |
| 1058 |
pushback(c); |
| 1059 |
} |
| 1060 |
tokenadd(prec); |
| 1061 |
} |
| 1062 |
} |
| 1063 |
pushback(c); |
| 1064 |
while ((c = nextc()) != '\'') |
| 1065 |
tokenadd(c); |
| 1066 |
printf("* string - %s\n", token); |
| 1067 |
yylval.sval = token; |
| 1068 |
return STRING_LITERAL; |
| 1069 |
|
| 1070 |
/* digit */ |
| 1071 |
case '0': case '1': case '2': case '3': case '4': |
| 1072 |
case '5': case '6': case '7': case '8': case '9': |
| 1073 |
newtoken(); |
| 1074 |
tokenadd(c); |
| 1075 |
while (c = nextc()) { |
| 1076 |
switch (c) { |
| 1077 |
case '0': case '1': case '2': case '3': case '4': |
| 1078 |
case '5': case '6': case '7': case '8': case '9': |
| 1079 |
tokenadd(c); |
| 1080 |
break; |
| 1081 |
|
| 1082 |
case 'r': |
| 1083 |
if (isbase || isfloat || isscaled) { |
| 1084 |
printf("* error base\n"); |
| 1085 |
return 0; |
| 1086 |
} |
| 1087 |
tokenadd(c); |
| 1088 |
isbase = 1; |
| 1089 |
break; |
| 1090 |
|
| 1091 |
case '.': |
| 1092 |
if (isbase || isfloat || isscaled) { |
| 1093 |
printf("* error float\n"); |
| 1094 |
return 0; |
| 1095 |
} |
| 1096 |
tokenadd(c); |
| 1097 |
isfloat = 1; |
| 1098 |
break; |
| 1099 |
|
| 1100 |
case 'e': |
| 1101 |
tokenadd(c); |
| 1102 |
if (!isbase) isexp = 1; |
| 1103 |
break; |
| 1104 |
|
| 1105 |
case 's': |
| 1106 |
tokenadd(c); |
| 1107 |
isscaled = 1; |
| 1108 |
break; |
| 1109 |
|
| 1110 |
case '-': |
| 1111 |
if (!isexp) { |
| 1112 |
printf("* error decimal\n"); |
| 1113 |
return 0; |
| 1114 |
} |
| 1115 |
tokenadd(c); |
| 1116 |
break; |
| 1117 |
|
| 1118 |
case 'a': case 'b': case 'c': case 'd': case 'f': |
| 1119 |
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': |
| 1120 |
if (!isbase) { |
| 1121 |
printf("* error base\n"); |
| 1122 |
return 0; |
| 1123 |
} |
| 1124 |
tokenadd(c); |
| 1125 |
break; |
| 1126 |
|
| 1127 |
default: |
| 1128 |
pushback(c); |
| 1129 |
if (isfloat) { |
| 1130 |
yylval.fval = strtod(token, NULL); |
| 1131 |
return FLOAT_LITERAL; |
| 1132 |
} else if (isscaled) { |
| 1133 |
yylval.sval = token; |
| 1134 |
return DECIMAL_LITERAL; |
| 1135 |
} else { |
| 1136 |
yylval.ival = strtol(token, NULL, 10); |
| 1137 |
if (yylval.ival == LONG_MAX || yylval.ival == LONG_MIN) |
| 1138 |
return LARGE_INTEGER_LITERAL; |
| 1139 |
else |
| 1140 |
return INTEGER_LITERAL; |
| 1141 |
} |
| 1142 |
} |
| 1143 |
} |
| 1144 |
|
| 1145 |
case ':': |
| 1146 |
c = nextc(); |
| 1147 |
if (c == '=') |
| 1148 |
return ASSIGNMENT; |
| 1149 |
else if (c == ':') |
| 1150 |
return SCOPE_SEPARATOR; |
| 1151 |
pushback(c); |
| 1152 |
return ':'; |
| 1153 |
|
| 1154 |
case '#': |
| 1155 |
if ((c = nextc()) == '<') { |
| 1156 |
in_data = 1; |
| 1157 |
return DATA_START; |
| 1158 |
} |
| 1159 |
pushback(c); |
| 1160 |
return '#'; |
| 1161 |
|
| 1162 |
case '.': case ';': case '^': case '|': case ',': |
| 1163 |
case '(': case ')': case '[': case ']': case '{': case '}': |
| 1164 |
return c; |
| 1165 |
|
| 1166 |
/* binary operators */ |
| 1167 |
case '!': case '%': case '&': case '*': case '+': case '-': |
| 1168 |
case '/': case '<': case '=': case '>': case '?': |
| 1169 |
case '@': case '\\': case '~': |
| 1170 |
newtoken(); |
| 1171 |
tokenadd(c); |
| 1172 |
while (peek_str("!%&*+-,/<=>?@\\~")) |
| 1173 |
tokenadd(nextc()); |
| 1174 |
printf("* binary op = %s\n", token); |
| 1175 |
yylval.sval = token; |
| 1176 |
return BINOP; |
| 1177 |
|
| 1178 |
default: |
| 1179 |
/* uri */ |
| 1180 |
len = 1; |
| 1181 |
newtoken(); |
| 1182 |
while (c != -1 && (isalnum(c) || c == '+' || c == '-' || c == '.')) { |
| 1183 |
tokenadd(c); |
| 1184 |
len++; |
| 1185 |
c = nextc(); |
| 1186 |
} |
| 1187 |
if (c == ':') { |
| 1188 |
if ((c = nextc()) == '/') { |
| 1189 |
if ((c = nextc()) == '/') { |
| 1190 |
tokenadd(':'); |
| 1191 |
tokenadd('/'); |
| 1192 |
tokenadd('/'); |
| 1193 |
while (isalnum(peekc) || peek_str("%:/?#[]@!$&()'*+,;=-._~")) |
| 1194 |
tokenadd(nextc()); |
| 1195 |
yylval.sval = token; |
| 1196 |
return URI; |
| 1197 |
} |
| 1198 |
pushback('/'); |
| 1199 |
pushback('/'); |
| 1200 |
len -= 2; |
| 1201 |
} |
| 1202 |
pushback(':'); |
| 1203 |
} |
| 1204 |
for (i = 0; i < len; i++) |
| 1205 |
pushback(0); |
| 1206 |
|
| 1207 |
/* identifier, etc. */ |
| 1208 |
newtoken(); |
| 1209 |
while (!peek_str(" \t\f\r\n\13'\"|0123456789.:;$!?+-*/<>=[](){}")) |
| 1210 |
tokenadd(nextc()); |
| 1211 |
if (IS_PATTERN_LV && next_pattern == 0) |
| 1212 |
next_pattern = 1; |
| 1213 |
if (peek(':')) { |
| 1214 |
tokenadd(nextc()); |
| 1215 |
printf("* keyword - %s\n", token); |
| 1216 |
if (tokencmp("category:")) |
| 1217 |
return CATEGORY_KEYWORD; |
| 1218 |
else if (tokencmp("timestamp:")) |
| 1219 |
return TIMESTAMP_KEYWORD; |
| 1220 |
else if (tokencmp("fields:")) |
| 1221 |
return FIELDS_KEYWORD; |
| 1222 |
else if (tokencmp("instanceVariableNames:")) |
| 1223 |
return INST_VARS_KEYWORD; |
| 1224 |
else if (tokencmp("classInstanceVariableNames:")) |
| 1225 |
return CLASS_VARS_KEYWORD; |
| 1226 |
else if (tokencmp("methodsFor:") || tokencmp("instanceMethodsFor:")) |
| 1227 |
return INST_METHODS_KEYWORD; |
| 1228 |
else if (tokencmp("classMethodsFor:")) |
| 1229 |
return CLASS_METHODS_KEYWORD; |
| 1230 |
else if (tokencmp("sharedVariablesFor:")) |
| 1231 |
return SHARED_VARS_KEYWORD; |
| 1232 |
else |
| 1233 |
return KEYWORD; |
| 1234 |
} |
| 1235 |
if (IS_NO_LV) { |
| 1236 |
if (tokencmp("class")) |
| 1237 |
return CLASS_START; |
| 1238 |
else if (tokencmp("module")) |
| 1239 |
return MODULE_START; |
| 1240 |
} |
| 1241 |
printf("* identifier - %s\n", token); |
| 1242 |
yylval.sval = token; |
| 1243 |
if (tokencmp("true")) return TRUE; |
| 1244 |
else if (tokencmp("false")) return FALSE; |
| 1245 |
else if (tokencmp("nil")) return NIL; |
| 1246 |
else if (tokencmp("self")) return SELF; |
| 1247 |
else if (tokencmp("super")) return SUPER; |
| 1248 |
else if (tokencmp("thisContext")) return THIS_CONTEXT; |
| 1249 |
return IDENTIFIER; |
| 1250 |
} |
| 1251 |
} |
| 1252 |
//printf("* Invalid char `\\%03o'\n", c); |
| 1253 |
return; |
| 1254 |
} |
| 1255 |
|
| 1256 |
static tree_node make_expr_node( node_type nodeType, |
| 1257 |
tree_node receiver, |
| 1258 |
OOP selector, |
| 1259 |
tree_node expression ) |
| 1260 |
{ |
| 1261 |
tree_node result; |
| 1262 |
|
| 1263 |
result = make_tree_node(nodeType); |
| 1264 |
result->v_expr.receiver = receiver; |
| 1265 |
result->v_expr.selector = selector; |
| 1266 |
result->v_expr.expression = expression; |
| 1267 |
return result; |
| 1268 |
} |
| 1269 |
|
| 1270 |
static tree_node make_tree_node( node_type nodeType ) |
| 1271 |
{ |
| 1272 |
tree_node result; |
| 1273 |
|
| 1274 |
result = (tree_node)malloc(sizeof(struct tree_node)); |
| 1275 |
result->nodeType = nodeType; |
| 1276 |
return result; |
| 1277 |
} |
| 1278 |
|
| 1279 |
static tree_node make_symbol( char *sval ) |
| 1280 |
{ |
| 1281 |
tree_node result; |
| 1282 |
|
| 1283 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1284 |
result->v_const.constType = CONST_SYMBOL; |
| 1285 |
result->v_const.val.oopVal = cw_boot_intern(sval); |
| 1286 |
|
| 1287 |
return result; |
| 1288 |
} |
| 1289 |
|
| 1290 |
static tree_node make_char( char cval ) |
| 1291 |
{ |
| 1292 |
tree_node result; |
| 1293 |
|
| 1294 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1295 |
result->v_const.constType = CONST_OOP; |
| 1296 |
result->v_const.val.oopVal = INT2CHAR(cval); |
| 1297 |
|
| 1298 |
return result; |
| 1299 |
} |
| 1300 |
|
| 1301 |
static tree_node make_string( char *sval ) |
| 1302 |
{ |
| 1303 |
tree_node result; |
| 1304 |
|
| 1305 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1306 |
result->v_const.constType = CONST_STRING; |
| 1307 |
result->v_const.val.oopVal = cw_byte_string_new2(sval); |
| 1308 |
|
| 1309 |
return result; |
| 1310 |
} |
| 1311 |
|
| 1312 |
static tree_node make_int( long ival ) |
| 1313 |
{ |
| 1314 |
tree_node result; |
| 1315 |
|
| 1316 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1317 |
result->v_const.constType = CONST_INT; |
| 1318 |
result->v_const.val.iVal = ival; |
| 1319 |
|
| 1320 |
return (result); |
| 1321 |
} |
| 1322 |
|
| 1323 |
static tree_node make_float( double fval ) |
| 1324 |
{ |
| 1325 |
tree_node result; |
| 1326 |
|
| 1327 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1328 |
result->v_const.constType = CONST_FLOAT; |
| 1329 |
result->v_const.val.fVal = fval; |
| 1330 |
|
| 1331 |
return result; |
| 1332 |
} |
| 1333 |
|
| 1334 |
static tree_node make_large_int( char *sval ) |
| 1335 |
{ |
| 1336 |
tree_node result; |
| 1337 |
|
| 1338 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1339 |
result->v_const.constType = CONST_LARGE_INT; |
| 1340 |
result->v_const.val.sVal = sval; |
| 1341 |
|
| 1342 |
return result; |
| 1343 |
} |
| 1344 |
|
| 1345 |
static tree_node make_decimal( char *sval ) |
| 1346 |
{ |
| 1347 |
tree_node result; |
| 1348 |
|
| 1349 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1350 |
result->v_const.constType = CONST_DECIMAL; |
| 1351 |
result->v_const.val.sVal = sval; |
| 1352 |
|
| 1353 |
return result; |
| 1354 |
} |
| 1355 |
|
| 1356 |
static tree_node make_array( tree_node aval ) |
| 1357 |
{ |
| 1358 |
tree_node result; |
| 1359 |
|
| 1360 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1361 |
result->v_const.constType = CONST_ARRAY; |
| 1362 |
result->v_const.val.aVal = aval; |
| 1363 |
|
| 1364 |
return result; |
| 1365 |
} |
| 1366 |
|
| 1367 |
static tree_node make_array_elt( tree_node elt ) |
| 1368 |
{ |
| 1369 |
return make_list_node(TREE_ARRAY_ELT_LIST, NULL, elt); |
| 1370 |
} |
| 1371 |
|
| 1372 |
static tree_node make_dynamic_array( tree_node statements ) |
| 1373 |
{ |
| 1374 |
tree_node result; |
| 1375 |
|
| 1376 |
result = make_tree_node(TREE_DYNAMIC_ARRAY); |
| 1377 |
result->v_const.constType = CONST_ARRAY; |
| 1378 |
result->v_const.val.aVal = statements; |
| 1379 |
|
| 1380 |
return result; |
| 1381 |
} |
| 1382 |
|
| 1383 |
static tree_node make_data( char *sval ) |
| 1384 |
{ |
| 1385 |
tree_node result; |
| 1386 |
|
| 1387 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1388 |
result->v_const.constType = CONST_DATA; |
| 1389 |
result->v_const.val.sVal = sval; |
| 1390 |
|
| 1391 |
return result; |
| 1392 |
} |
| 1393 |
|
| 1394 |
static tree_node make_uri( char *sval ) |
| 1395 |
{ |
| 1396 |
tree_node result; |
| 1397 |
|
| 1398 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1399 |
result->v_const.constType = CONST_URI; |
| 1400 |
result->v_const.val.sVal = sval; |
| 1401 |
|
| 1402 |
return result; |
| 1403 |
} |
| 1404 |
|
| 1405 |
static tree_node make_binding( tree_node variables ) |
| 1406 |
{ |
| 1407 |
tree_node result; |
| 1408 |
|
| 1409 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1410 |
result->v_const.constType = CONST_BINDING; |
| 1411 |
result->v_const.val.aVal = variables; |
| 1412 |
|
| 1413 |
return result; |
| 1414 |
} |
| 1415 |
|
| 1416 |
static tree_node make_pseudo_variable( int pseudoType ) |
| 1417 |
{ |
| 1418 |
tree_node result; |
| 1419 |
|
| 1420 |
result = make_tree_node(TREE_CONST_EXPR); |
| 1421 |
result->v_const.constType = pseudoType; |
| 1422 |
|
| 1423 |
return result; |
| 1424 |
} |
| 1425 |
|
| 1426 |
static tree_node make_variable( char *name ) |
| 1427 |
{ |
| 1428 |
return make_list_node(TREE_VARIABLE_NODE, name, NULL); |
| 1429 |
} |
| 1430 |
|
| 1431 |
static tree_node make_assign( tree_node variables, |
| 1432 |
tree_node expression ) |
| 1433 |
{ |
| 1434 |
return make_expr_node(TREE_ASSIGN_EXPR, variables, Pnil, expression); |
| 1435 |
} |
| 1436 |
|
| 1437 |
static tree_node make_assignment_list( tree_node variable ) |
| 1438 |
{ |
| 1439 |
return make_list_node(TREE_VAR_ASSIGN_LIST, NULL, variable); |
| 1440 |
} |
| 1441 |
|
| 1442 |
static tree_node make_return( tree_node expression ) |
| 1443 |
{ |
| 1444 |
return make_expr_node(TREE_RETURN_EXPR, expression, Pnil, NULL); |
| 1445 |
} |
| 1446 |
|
| 1447 |
static tree_node make_keyword_expr( tree_node receiver, |
| 1448 |
tree_node keywordMessage ) |
| 1449 |
{ |
| 1450 |
return make_expr_node(TREE_KEYWORD_EXPR, receiver, Pnil, keywordMessage); |
| 1451 |
} |
| 1452 |
|
| 1453 |
static tree_node make_keyword_list( char *keyword, tree_node expression ) |
| 1454 |
{ |
| 1455 |
return make_list_node(TREE_KEYWORD_LIST, keyword, expression); |
| 1456 |
} |
| 1457 |
|
| 1458 |
static tree_node make_statement_list( tree_node expression ) |
| 1459 |
{ |
| 1460 |
return make_list_node(TREE_STATEMENT_LIST, NULL, expression); |
| 1461 |
} |
| 1462 |
|
| 1463 |
static tree_node make_cascaded_message( tree_node messageExpr, |
| 1464 |
tree_node cascadedMessages ) |
| 1465 |
{ |
| 1466 |
return make_expr_node(TREE_CASCADE_EXPR, |
| 1467 |
messageExpr, NULL, cascadedMessages); |
| 1468 |
} |
| 1469 |
|
| 1470 |
static tree_node make_unary_expr( tree_node receiver, char *unarySelectorExpr ) |
| 1471 |
{ |
| 1472 |
OOP selector; |
| 1473 |
|
| 1474 |
selector = cw_boot_intern(unarySelectorExpr); |
| 1475 |
return make_expr_node(TREE_UNARY_EXPR, receiver, selector, NULL); |
| 1476 |
} |
| 1477 |
|
| 1478 |
static tree_node make_binary_expr( tree_node receiver, |
| 1479 |
char *binaryOp, |
| 1480 |
tree_node argument ) |
| 1481 |
{ |
| 1482 |
OOP selector; |
| 1483 |
|
| 1484 |
selector = cw_boot_intern(binaryOp); |
| 1485 |
return make_expr_node(TREE_BINARY_EXPR, receiver, selector, argument); |
| 1486 |
} |
| 1487 |
|
| 1488 |
static tree_node make_message_list( tree_node messageElt ) |
| 1489 |
{ |
| 1490 |
return make_list_node(TREE_MESSAGE_LIST, NULL, messageElt); |
| 1491 |
} |
| 1492 |
|
| 1493 |
static tree_node make_block( tree_node arguments, |
| 1494 |
tree_node temporaries, |
| 1495 |
tree_node statements ) |
| 1496 |
{ |
| 1497 |
tree_node result; |
| 1498 |
|
| 1499 |
result = make_tree_node(TREE_BLOCK_NODE); |
| 1500 |
result->v_block.arguments = arguments; |
| 1501 |
result->v_block.temporaries = temporaries; |
| 1502 |
result->v_block.statements = statements; |
| 1503 |
return result; |
| 1504 |
} |
| 1505 |
|
| 1506 |
static tree_node make_variable_list( tree_node variable ) |
| 1507 |
{ |
| 1508 |
variable->nodeType = TREE_VAR_DECL_LIST; |
| 1509 |
return variable; |
| 1510 |
} |
| 1511 |
|
| 1512 |
static tree_node make_list_node( node_type nodeType, |
| 1513 |
char *name, |
| 1514 |
tree_node value ) |
| 1515 |
{ |
| 1516 |
tree_node result; |
| 1517 |
|
| 1518 |
result = make_tree_node(nodeType); |
| 1519 |
result->v_list.name = name; |
| 1520 |
result->v_list.value = value; |
| 1521 |
result->v_list.next = NULL; |
| 1522 |
result->v_list.nextAddr = &result->v_list.next; |
| 1523 |
return result; |
| 1524 |
} |
| 1525 |
|
| 1526 |
static void add_node( tree_node n1, tree_node n2 ) |
| 1527 |
{ |
| 1528 |
*(n1->v_list.nextAddr) = n2; |
| 1529 |
n1->v_list.nextAddr = n2->v_list.nextAddr; |
| 1530 |
} |
| 1531 |
|
| 1532 |
int main( int argc, char **argv ) |
| 1533 |
{ |
| 1534 |
FILE *fp; |
| 1535 |
int c, val; |
| 1536 |
long fsize; |
| 1537 |
|
| 1538 |
if ((fp=fopen(argv[1],"r"))==NULL) { |
| 1539 |
printf("error: input file\n"); |
| 1540 |
exit(1); |
| 1541 |
} |
| 1542 |
|
| 1543 |
cw_init_proto_oops(); |
| 1544 |
fseek(fp, 0, SEEK_END); |
| 1545 |
fsize = ftell(fp); |
| 1546 |
fseek(fp, 0, SEEK_SET); |
| 1547 |
lex_str = malloc(fsize); |
| 1548 |
fread(lex_str, sizeof(char), fsize, fp); |
| 1549 |
fclose(fp); |
| 1550 |
lex_p = 0; |
| 1551 |
lex_pend = fsize; |
| 1552 |
yyparse(); |
| 1553 |
|
| 1554 |
return; |
| 1555 |
} |