#include "wsint.h"#include "wsgram.h"Include dependency graph for wsstree.c:

Go to the source code of this file.
|
||||||||||||||||
|
Definition at line 873 of file wsstree.c. References WsExpressionRec::line, WsCompilerRec::pool_stree, WsExpressionRec::type, ws_error_memory(), ws_f_calloc(), WsCompiler, and WsExpression. Referenced by ws_expr_assign(), ws_expr_binary(), ws_expr_call(), ws_expr_comma(), ws_expr_conditional(), ws_expr_const_false(), ws_expr_const_float(), ws_expr_const_integer(), ws_expr_const_invalid(), ws_expr_const_string(), ws_expr_const_true(), ws_expr_logical(), ws_expr_postfix_var(), ws_expr_symbol(), ws_expr_unary(), and ws_expr_unary_var(). 00875 {
00876 WsExpression *expr = ws_f_calloc(compiler->pool_stree, 1, sizeof(*expr));
00877
00878 if (expr == NULL)
00879 ws_error_memory(compiler);
00880 else {
00881 expr->type = type;
00882 expr->line = line;
00883 }
00884
00885 return expr;
00886 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 306 of file wsstree.c. References ws_free(). Referenced by ws_function_hash_create(). 00307 {
00308 ws_free(item);
00309 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1133 of file wsstree.c. References WsListItemRec::data, WsVarDecRec::expr, WsListRec::head, WsVarDecRec::name, WsListItemRec::next, WsNamespaceRec::vindex, ws_asm_link(), WS_ASM_P_STORE_VAR, ws_asm_variable(), ws_expr_linearize(), WS_TRUE, ws_variable_define(), WsCompiler, WsList, WsListItem, WsNamespace, and WsVarDec. Referenced by ws_stmt_linearize(). 01135 {
01136 WsNamespace *ns;
01137 WsListItem *li;
01138
01139 /* For each variable, declared with this list. */
01140 for (li = list->head; li; li = li->next) {
01141 WsVarDec *vardec = li->data;
01142
01143 ns = ws_variable_define(compiler, line, WS_TRUE, vardec->name);
01144 if (ns && vardec->expr) {
01145 ws_expr_linearize(compiler, vardec->expr);
01146
01147 /* Emit an instruction to store the initialization
01148 value to the variable. */
01149 ws_asm_link(compiler,
01150 ws_asm_variable(compiler, line, WS_ASM_P_STORE_VAR,
01151 ns->vindex));
01152 }
01153 }
01154 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 208 of file wsstree.c. References ws_free(). Referenced by ws_pragma_use_hash_create(). 00209 {
00210 ws_free(item);
00211 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1372 of file wsstree.c. References WsStatementRec::first_line, WsStatementRec::last_line, WsCompilerRec::pool_stree, WsStatementRec::type, ws_error_memory(), ws_f_calloc(), WsCompiler, and WsStatement. Referenced by ws_stmt_block(), ws_stmt_break(), ws_stmt_continue(), ws_stmt_empty(), ws_stmt_expr(), ws_stmt_for(), ws_stmt_if(), ws_stmt_return(), ws_stmt_variable(), and ws_stmt_while(). 01374 {
01375 WsStatement *stmt = ws_f_calloc(compiler->pool_stree, 1, sizeof(*stmt));
01376
01377 if (stmt == NULL)
01378 ws_error_memory(compiler);
01379 else {
01380 stmt->type = type;
01381 stmt->first_line = first_line;
01382 stmt->last_line = last_line;
01383 }
01384
01385 return stmt;
01386 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 148 of file wsstree.c. References ws_free(). Referenced by ws_variable_hash_create(). 00149 {
00150 ws_free(item);
00151 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 903 of file wsstree.c. References WsExpressionRec::assign, WsExpressionRec::expr, expr_alloc(), WsExpressionRec::identifier, WsExpressionRec::op, WsCompilerRec::pool_stree, WsExpressionRec::u, ws_error_memory(), WS_EXPR_ASSIGN, ws_f_strdup(), ws_lexer_free_block(), WsCompilerPtr, and WsExpression. Referenced by yyparse(). 00905 {
00906 WsExpression *e = expr_alloc(compiler, WS_EXPR_ASSIGN, line);
00907
00908 if (e) {
00909 e->u.assign.identifier = ws_f_strdup(compiler->pool_stree, identifier);
00910 if (e->u.assign.identifier == NULL)
00911 ws_error_memory(compiler);
00912
00913 e->u.assign.op = op;
00914 e->u.assign.expr = expr;
00915 }
00916
00917 /* Free the identifier symbol since it allocated from the system
00918 heap. */
00919 ws_lexer_free_block(compiler, identifier);
00920
00921 return e;
00922 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 956 of file wsstree.c. References WsExpressionRec::binary, expr_alloc(), WsExpressionRec::left, WsExpressionRec::right, WsExpressionRec::type, WsExpressionRec::u, WS_EXPR_BINARY, WsCompilerPtr, and WsExpression. Referenced by yyparse(). 00958 {
00959 WsExpression *expr = expr_alloc(compiler, WS_EXPR_BINARY, line);
00960
00961 if (expr) {
00962 expr->u.binary.type = type;
00963 expr->u.binary.left = left;
00964 expr->u.binary.right = right;
00965 }
00966
00967 return expr;
00968 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 1028 of file wsstree.c. References WsExpressionRec::arguments, WsExpressionRec::base, WsExpressionRec::call, expr_alloc(), name, WsExpressionRec::name, WsCompilerRec::pool_stree, WsExpressionRec::type, WsExpressionRec::u, ws_error_memory(), WS_EXPR_CALL, ws_f_strdup(), ws_lexer_free_block(), WsCompiler, WsExpression, and WsList. 01030 {
01031 WsExpression *expr = expr_alloc(compiler, WS_EXPR_CALL, line);
01032
01033 if (expr) {
01034 expr->u.call.type = type;
01035 expr->u.call.base = ws_f_strdup(compiler->pool_stree, base);
01036 expr->u.call.name = ws_f_strdup(compiler->pool_stree, name);
01037 expr->u.call.arguments = arguments;
01038
01039 if ((base && expr->u.call.base == NULL)
01040 || (name && expr->u.call.name == NULL))
01041 ws_error_memory(compiler);
01042 }
01043
01044 ws_lexer_free_block(compiler, base);
01045 ws_lexer_free_block(compiler, name);
01046
01047 return expr;
01048 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 889 of file wsstree.c. References WsExpressionRec::comma, expr_alloc(), WsExpressionRec::left, WsExpressionRec::right, WsExpressionRec::u, WS_EXPR_COMMA, WsCompilerPtr, and WsExpression. Referenced by yyparse(). 00891 {
00892 WsExpression *expr = expr_alloc(compiler, WS_EXPR_COMMA, line);
00893
00894 if (expr) {
00895 expr->u.comma.left = left;
00896 expr->u.comma.right = right;
00897 }
00898
00899 return expr;
00900 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 925 of file wsstree.c. References WsExpressionRec::conditional, WsExpressionRec::e_cond, WsExpressionRec::e_else, WsExpressionRec::e_then, expr_alloc(), WsExpressionRec::u, WS_EXPR_CONDITIONAL, WsCompilerPtr, and WsExpression. Referenced by yyparse(). 00928 {
00929 WsExpression *e = expr_alloc(compiler, WS_EXPR_CONDITIONAL, line);
00930
00931 if (e) {
00932 e->u.conditional.e_cond = e_cond;
00933 e->u.conditional.e_then = e_then;
00934 e->u.conditional.e_else = e_else;
00935 }
00936
00937 return e;
00938 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1080 of file wsstree.c. References expr_alloc(), WS_EXPR_CONST_FALSE, WsCompiler, and WsExpression. 01081 {
01082 return expr_alloc(compiler, WS_EXPR_CONST_FALSE, line);
01083 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1100 of file wsstree.c. References expr_alloc(), WsExpressionRec::fval, WsExpressionRec::u, WS_EXPR_CONST_FLOAT, WsCompiler, and WsExpression. 01102 {
01103 WsExpression *expr = expr_alloc(compiler, WS_EXPR_CONST_FLOAT, line);
01104
01105 if (expr)
01106 expr->u.fval = fval;
01107
01108 return expr;
01109 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1086 of file wsstree.c. References expr_alloc(), WsExpressionRec::integer, WsExpressionRec::ival, WsExpressionRec::sign, WsExpressionRec::u, WS_EXPR_CONST_INTEGER, WsCompiler, and WsExpression. 01088 {
01089 WsExpression *expr = expr_alloc(compiler, WS_EXPR_CONST_INTEGER, line);
01090
01091 if (expr) {
01092 expr->u.integer.sign = 1;
01093 expr->u.integer.ival = ival;
01094 }
01095
01096 return expr;
01097 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1068 of file wsstree.c. References expr_alloc(), WS_EXPR_CONST_INVALID, WsCompiler, and WsExpression. 01069 {
01070 return expr_alloc(compiler, WS_EXPR_CONST_INVALID, line);
01071 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1112 of file wsstree.c. References WsUtf8StringRec::data, expr_alloc(), WsUtf8StringRec::len, WsCompilerRec::pool_stree, string, WsExpressionRec::string, WsExpressionRec::u, ws_error_memory(), WS_EXPR_CONST_STRING, ws_f_memdup(), ws_lexer_free_utf8(), WsCompiler, WsExpression, and WsUtf8String. 01114 {
01115 WsExpression *expr = expr_alloc(compiler, WS_EXPR_CONST_STRING, line);
01116
01117 if (expr) {
01118 expr->u.string.len = string->len;
01119 expr->u.string.data = ws_f_memdup(compiler->pool_stree,
01120 string->data, string->len);
01121 if (expr->u.string.data == NULL)
01122 ws_error_memory(compiler);
01123 }
01124
01125 ws_lexer_free_utf8(compiler, string);
01126
01127 return expr;
01128 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1074 of file wsstree.c. References expr_alloc(), WS_EXPR_CONST_TRUE, WsCompiler, and WsExpression. 01075 {
01076 return expr_alloc(compiler, WS_EXPR_CONST_TRUE, line);
01077 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 395 of file wsstree.c. References WsExpressionRec::addp, WsExpressionRec::arguments, WsExpressionRec::assign, WsExpressionRec::base, WsCompilerRec::bc, WsExpressionRec::binary, WsExpressionRec::call, WsExpressionRec::comma, WsExpressionRec::conditional, WsUtf8StringRec::data, WsListItemRec::data, WsFunctionHashRec::defined, WsExpressionRec::e_cond, WsExpressionRec::e_else, WsExpressionRec::e_then, WsExpressionRec::expr, WsFunctionHashRec::findex, WsCompilerRec::functions, WsExpressionRec::fval, WsListRec::head, WsExpressionRec::identifier, WsExpressionRec::integer, WsExpressionRec::ival, WsExpressionRec::left, WsUtf8StringRec::len, WsExpressionRec::line, WsExpressionRec::logical, WsExpressionRec::name, WsListItemRec::next, WsListRec::num_items, WsExpressionRec::op, WsFunctionRec::params, WsExpressionRec::postfix_var, WsCompilerRec::pragma_use_hash, WsExpressionRec::right, WsExpressionRec::sign, WsExpressionRec::string, WsExpressionRec::symbol, tADDA, tANDA, tDIVA, tIDIVA, tLSHIFTA, tMULA, tORA, tREMA, tRSSHIFTA, tRSZSHIFTA, tSUBA, tXORA, WsExpressionRec::type, WsExpressionRec::u, WsExpressionRec::unary, WsExpressionRec::unary_var, WsPragmaUseRec::urlindex, WsExpressionRec::variable, WsNamespaceRec::vindex, WS_ASM_ADD, WS_ASM_ADD_ASG, WS_ASM_B_AND, WS_ASM_B_LSHIFT, WS_ASM_B_OR, WS_ASM_B_RSSHIFT, WS_ASM_B_RSZSHIFT, WS_ASM_B_XOR, ws_asm_branch(), ws_asm_call(), ws_asm_call_lib(), ws_asm_call_url(), WS_ASM_CONST_0, WS_ASM_CONST_1, WS_ASM_CONST_ES, WS_ASM_CONST_FALSE, WS_ASM_CONST_INVALID, WS_ASM_CONST_TRUE, WS_ASM_DECR_VAR, WS_ASM_DIV, WS_ASM_IDIV, ws_asm_ins(), ws_asm_label(), ws_asm_link(), ws_asm_load_const(), WS_ASM_MUL, WS_ASM_P_INCR_VAR, WS_ASM_P_JUMP, WS_ASM_P_LOAD_VAR, WS_ASM_P_STORE_VAR, WS_ASM_P_TJUMP, WS_ASM_POP, WS_ASM_REM, WS_ASM_SUB, WS_ASM_SUB_ASG, WS_ASM_TOBOOL, ws_asm_variable(), ws_bc_add_const_float(), ws_bc_add_const_int(), ws_bc_add_const_utf8_string(), ws_error_memory(), WS_EXPR_ASSIGN, WS_EXPR_BINARY, WS_EXPR_CALL, WS_EXPR_COMMA, WS_EXPR_CONDITIONAL, WS_EXPR_CONST_FALSE, WS_EXPR_CONST_FLOAT, WS_EXPR_CONST_INTEGER, WS_EXPR_CONST_INVALID, WS_EXPR_CONST_STRING, WS_EXPR_CONST_TRUE, ws_expr_linearize(), WS_EXPR_LOGICAL, WS_EXPR_POSTFIX_VAR, WS_EXPR_SYMBOL, WS_EXPR_UNARY, WS_EXPR_UNARY_VAR, ws_fatal(), ws_function_hash(), ws_hash_get(), WS_INT32_MAX, ws_src_error(), ws_stdlib_function(), ws_variable_lookup(), WsAsmIns, WsBool, WsCompiler, WsExpression, WsFunctionHash, WsInt32, WsListItem, WsNamespace, WsPragmaUse, WsUInt16, and WsUInt8. 00396 {
00397 WsListItem *li;
00398 WsAsmIns *ins;
00399
00400 switch (expr->type) {
00401 case WS_EXPR_COMMA:
00402 /* Linearize left. */
00403 ws_expr_linearize(compiler, expr->u.comma.left);
00404
00405 /* Pop its result. */
00406 ws_asm_link(compiler, ws_asm_ins(compiler, expr->line, WS_ASM_POP));
00407
00408 /* Linearize right */
00409 ws_expr_linearize(compiler, expr->u.comma.right);
00410 break;
00411
00412 case WS_EXPR_ASSIGN:
00413 {
00414 WsNamespace *ns = ws_variable_lookup(compiler,
00415 expr->u.assign.identifier);
00416
00417 if (ns == NULL) {
00418 /* Unknown identifier. */
00419 ws_src_error(compiler, expr->line, "unknown variable `%s'",
00420 expr->u.symbol);
00421 return;
00422 }
00423
00424 if (expr->u.assign.op == '=') {
00425 /* Evaluate the expression. */
00426 ws_expr_linearize(compiler, expr->u.assign.expr);
00427
00428 /* Store the value to the variable. */
00429 ws_asm_link(compiler,
00430 ws_asm_variable(compiler, expr->line,
00431 WS_ASM_P_STORE_VAR, ns->vindex));
00432 } else if (expr->u.assign.op == tADDA) {
00433 /* Linearize the expression. */
00434 ws_expr_linearize(compiler, expr->u.assign.expr);
00435
00436 /* Add it to the variable. */
00437 ws_asm_link(compiler,
00438 ws_asm_variable(compiler, expr->line,
00439 WS_ASM_ADD_ASG, ns->vindex));
00440 } else if (expr->u.assign.op == tSUBA) {
00441 /* Linearize the expression. */
00442 ws_expr_linearize(compiler, expr->u.assign.expr);
00443
00444 /* Substract it from the variable. */
00445 ws_asm_link(compiler,
00446 ws_asm_variable(compiler, expr->line,
00447 WS_ASM_SUB_ASG, ns->vindex));
00448 } else {
00449 /* Load the old value from the variable. */
00450 ws_asm_link(compiler,
00451 ws_asm_variable(compiler, expr->line,
00452 WS_ASM_P_LOAD_VAR, ns->vindex));
00453
00454 /* Evaluate the expression. */
00455 ws_expr_linearize(compiler, expr->u.assign.expr);
00456
00457 /* Perform the operand. */
00458 ins = NULL;
00459 switch (expr->u.assign.op) {
00460 case tMULA:
00461 ins = ws_asm_ins(compiler, expr->line, WS_ASM_MUL);
00462 break;
00463
00464 case tDIVA:
00465 ins = ws_asm_ins(compiler, expr->line, WS_ASM_DIV);
00466 break;
00467
00468 case tREMA:
00469 ins = ws_asm_ins(compiler, expr->line, WS_ASM_REM);
00470 break;
00471
00472 case tADDA:
00473 ins = ws_asm_ins(compiler, expr->line, WS_ASM_ADD);
00474 break;
00475
00476 case tSUBA:
00477 ins = ws_asm_ins(compiler, expr->line, WS_ASM_SUB);
00478 break;
00479
00480 case tLSHIFTA:
00481 ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_LSHIFT);
00482 break;
00483
00484 case tRSSHIFTA:
00485 ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_RSSHIFT);
00486 break;
00487
00488 case tRSZSHIFTA:
00489 ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_RSZSHIFT);
00490 break;
00491
00492 case tANDA:
00493 ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_AND);
00494 break;
00495
00496 case tXORA:
00497 ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_XOR);
00498 break;
00499
00500 case tORA:
00501 ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_OR);
00502 break;
00503
00504 case tIDIVA:
00505 ins = ws_asm_ins(compiler, expr->line, WS_ASM_IDIV);
00506 break;
00507
00508 default:
00509 ws_fatal("ws_expr_linearize(): unknown assignment operand %x",
00510 expr->u.assign.op);
00511 break;
00512 }
00513 ws_asm_link(compiler, ins);
00514
00515 /* Store the value to the variable. */
00516 ws_asm_link(compiler,
00517 ws_asm_variable(compiler, expr->line,
00518 WS_ASM_P_STORE_VAR, ns->vindex));
00519 }
00520 /* The value of the assignment expression is the value
00521 assigned. So, we must load the value from the variable.
00522 This would also be a good place for the `dup' operand but
00523 we lose since we don't have it. */
00524 ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,
00525 WS_ASM_P_LOAD_VAR, ns->vindex));
00526 }
00527 break;
00528
00529 case WS_EXPR_CONDITIONAL:
00530 {
00531 WsAsmIns *l_else = ws_asm_label(compiler, expr->line);
00532 WsAsmIns *l_end = ws_asm_label(compiler, expr->line);
00533
00534 /* Linearize condition. */
00535 ws_expr_linearize(compiler, expr->u.conditional.e_cond);
00536
00537 /* If the result if false, jump to the else-branch. */
00538 ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,
00539 WS_ASM_P_TJUMP, l_else));
00540
00541 /* Linearize the then-expression and jump out. */
00542 ws_expr_linearize(compiler, expr->u.conditional.e_then);
00543 ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,
00544 WS_ASM_P_JUMP, l_end));
00545
00546 /* The else-branch. */
00547 ws_asm_link(compiler, l_else);
00548 ws_expr_linearize(compiler, expr->u.conditional.e_else);
00549
00550 /* Insert the end label. */
00551 ws_asm_link(compiler, l_end);
00552 }
00553 break;
00554
00555 case WS_EXPR_LOGICAL:
00556 {
00557 WsAsmIns *l_out = ws_asm_label(compiler, expr->line);
00558
00559 /* Linearize the left-hand size expression. */
00560 ws_expr_linearize(compiler, expr->u.logical.left);
00561
00562 /* Short-circuit check. The type of the logical expression is
00563 the short-circuit byte-code operand. */
00564 ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
00565 expr->u.logical.type));
00566 ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,
00567 WS_ASM_P_TJUMP, l_out));
00568
00569 /* Linearize the right-hand size expression. */
00570 ws_expr_linearize(compiler, expr->u.logical.right);
00571
00572 /* The result of a logical expression should be boolean.
00573 * Control statements do automatic conversion, but typeof()
00574 * does not. */
00575 ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
00576 WS_ASM_TOBOOL));
00577
00578 /* Insert the end label. */
00579 ws_asm_link(compiler, l_out);
00580 }
00581 break;
00582
00583 case WS_EXPR_BINARY:
00584 /* Linearize left and right. */
00585 ws_expr_linearize(compiler, expr->u.binary.left);
00586 ws_expr_linearize(compiler, expr->u.binary.right);
00587
00588 /* The type of the binary expression is the byte-code opcode. */
00589 ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
00590 expr->u.binary.type));
00591 break;
00592
00593 case WS_EXPR_UNARY:
00594 /* Linearize the expression. */
00595 ws_expr_linearize(compiler, expr->u.unary.expr);
00596
00597 /* The type of the unary expression is the byte-code opcode. */
00598 ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
00599 expr->u.unary.type));
00600 break;
00601
00602 case WS_EXPR_UNARY_VAR:
00603 {
00604 WsNamespace *ns = ws_variable_lookup(compiler,
00605 expr->u.unary_var.variable);
00606 if (ns == NULL) {
00607 /* An unknown identifier. */
00608 ws_src_error(compiler, expr->line, "unknown variable `%s'",
00609 expr->u.unary_var.variable);
00610 return;
00611 }
00612
00613 /* First, do the operation. */
00614 if (expr->u.unary_var.addp)
00615 ws_asm_link(compiler,
00616 ws_asm_variable(compiler, expr->line, WS_ASM_P_INCR_VAR,
00617 ns->vindex));
00618 else
00619 ws_asm_link(compiler,
00620 ws_asm_variable(compiler, expr->line, WS_ASM_DECR_VAR,
00621 ns->vindex));
00622
00623 /* Second, load the new value of the variable. */
00624 ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,
00625 WS_ASM_P_LOAD_VAR, ns->vindex));
00626 }
00627 break;
00628
00629 case WS_EXPR_POSTFIX_VAR:
00630 {
00631 WsNamespace *ns = ws_variable_lookup(compiler,
00632 expr->u.postfix_var.variable);
00633 if (ns == NULL) {
00634 /* An unknown identifier. */
00635 ws_src_error(compiler, expr->line, "unknown variable `%s'",
00636 expr->u.postfix_var.variable);
00637 return;
00638 }
00639
00640 /* First, load the old value of the variable. */
00641 ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,
00642 WS_ASM_P_LOAD_VAR, ns->vindex));
00643
00644 /* Second, do the operation. */
00645 if (expr->u.unary_var.addp)
00646 ws_asm_link(compiler,
00647 ws_asm_variable(compiler, expr->line, WS_ASM_P_INCR_VAR,
00648 ns->vindex));
00649 else
00650 ws_asm_link(compiler,
00651 ws_asm_variable(compiler, expr->line, WS_ASM_DECR_VAR,
00652 ns->vindex));
00653 }
00654 break;
00655
00656 case WS_EXPR_CALL:
00657 /* First, evaluate the arguments. */
00658 for (li = expr->u.call.arguments->head; li; li = li->next)
00659 ws_expr_linearize(compiler, li->data);
00660
00661 /* Second, emit the call instruction. */
00662 switch (expr->u.call.type) {
00663 case ' ': /* LocalScriptFunctionCall */
00664 {
00665 WsFunctionHash *f = ws_function_hash(compiler, expr->u.call.name);
00666
00667 if (f == NULL || !f->defined)
00668 {
00669 ws_src_error(compiler, expr->line,
00670 "unknown local function `%s'",
00671 expr->u.call.name);
00672 return;
00673 }
00674
00675 /* Check that the function is called with correct amount
00676 of arguments. */
00677 if (expr->u.call.arguments->num_items
00678 != compiler->functions[f->findex].params->num_items)
00679 {
00680 ws_src_error(compiler, expr->line,
00681 "invalid amount of arguments for `%s': "
00682 "expected %u, got %u",
00683 expr->u.call.name,
00684 compiler->functions[f->findex].params->num_items,
00685 expr->u.call.arguments->num_items);
00686 return;
00687 }
00688
00689 /* Emit assembler. */
00690 ws_asm_link(compiler, ws_asm_call(compiler, expr->line,
00691 f->findex));
00692 }
00693 break;
00694
00695 case '#': /* ExternalScriptFunctionCall */
00696 {
00697 WsPragmaUse *use = ws_hash_get(compiler->pragma_use_hash,
00698 expr->u.call.base);
00699 WsUInt16 findex;
00700
00701 if (use == NULL)
00702 {
00703 ws_src_error(compiler, expr->line,
00704 "unknown external compilation unit `%s'",
00705 expr->u.call.base);
00706 return;
00707 }
00708
00709 /* Insert the function name to the byte-code pool. */
00710 if (!ws_bc_add_const_utf8_string(
00711 compiler->bc, &findex,
00712 (unsigned char *) expr->u.call.name,
00713 strlen(expr->u.call.name)))
00714 {
00715 ws_error_memory(compiler);
00716 return;
00717 }
00718
00719 /* Emit assembler. */
00720 ws_asm_link(compiler,
00721 ws_asm_call_url(compiler, expr->line,
00722 findex, use->urlindex,
00723 expr->u.call.arguments->num_items));
00724 }
00725 break;
00726
00727 case '.': /* LibraryFunctionCall */
00728 {
00729 WsUInt16 lindex;
00730 WsUInt8 findex;
00731 WsUInt8 num_args;
00732 WsBool lindex_found;
00733 WsBool findex_found;
00734
00735 if (!ws_stdlib_function(expr->u.call.base, expr->u.call.name,
00736 &lindex, &findex, &num_args,
00737 &lindex_found, &findex_found))
00738 {
00739 if (!lindex_found)
00740 ws_src_error(compiler, expr->line,
00741 "unknown system library `%s'",
00742 expr->u.call.base);
00743 else
00744 ws_src_error(compiler, expr->line,
00745 "unknown library function `%s.%s'",
00746 expr->u.call.base, expr->u.call.name);
00747
00748 return;
00749 }
00750 /* Check the argument count. */
00751 if (expr->u.call.arguments->num_items != num_args)
00752 {
00753 ws_src_error(compiler, expr->line,
00754 "invalid amount of arguments for `%s.%s': "
00755 "expected %u, got %u",
00756 expr->u.call.base, expr->u.call.name,
00757 num_args, expr->u.call.arguments->num_items);
00758 return;
00759 }
00760
00761 /* Emit assembler. */
00762 ws_asm_link(compiler, ws_asm_call_lib(compiler, expr->line, findex,
00763 lindex));
00764 }
00765 break;
00766
00767 default:
00768 ws_fatal("ws_expr_linearize(): unknown call expression type %x",
00769 expr->u.call.type);
00770 break;
00771 }
00772 break;
00773
00774 case WS_EXPR_SYMBOL:
00775 {
00776 WsNamespace *ns = ws_variable_lookup(compiler, expr->u.symbol);
00777
00778 if (ns == NULL) {
00779 /* An unknown identifier. */
00780 ws_src_error(compiler, expr->line, "unknown variable `%s'",
00781 expr->u.symbol);
00782 return;
00783 }
00784
00785 /* Create a load instruction for the variable. */
00786 ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,
00787 WS_ASM_P_LOAD_VAR, ns->vindex));
00788 }
00789 break;
00790
00791 case WS_EXPR_CONST_INVALID:
00792 ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
00793 WS_ASM_CONST_INVALID));
00794 break;
00795
00796 case WS_EXPR_CONST_TRUE:
00797 ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
00798 WS_ASM_CONST_TRUE));
00799 break;
00800
00801 case WS_EXPR_CONST_FALSE:
00802 ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
00803 WS_ASM_CONST_FALSE));
00804 break;
00805
00806
00807 case WS_EXPR_CONST_INTEGER:
00808 if (expr->u.integer.ival == 0)
00809 ins = ws_asm_ins(compiler, expr->line, WS_ASM_CONST_0);
00810 else if (expr->u.integer.ival == 1 && expr->u.integer.sign == 1)
00811 ins = ws_asm_ins(compiler, expr->line, WS_ASM_CONST_1);
00812 else {
00813 WsUInt16 cindex;
00814 WsInt32 ival;
00815
00816 if (expr->u.integer.sign >= 0) {
00817 if (expr->u.integer.ival > (WsUInt32) WS_INT32_MAX)
00818 ws_src_error(compiler, expr->line,
00819 "integer literal too large");
00820 ival = expr->u.integer.ival;
00821 } else {
00822 if (expr->u.integer.ival > (WsUInt32) WS_INT32_MAX + 1)
00823 ws_src_error(compiler, expr->line, "integer too small");
00824 ival = - (WsInt32) expr->u.integer.ival;
00825 }
00826
00827 if (!ws_bc_add_const_int(compiler->bc, &cindex, ival)) {
00828 ws_error_memory(compiler);
00829 return;
00830 }
00831 ins = ws_asm_load_const(compiler, expr->line, cindex);
00832 }
00833
00834 ws_asm_link(compiler, ins);
00835 break;
00836
00837 case WS_EXPR_CONST_FLOAT:
00838 {
00839 WsUInt16 cindex;
00840
00841 if (!ws_bc_add_const_float(compiler->bc, &cindex, expr->u.fval)) {
00842 ws_error_memory(compiler);
00843 return;
00844 }
00845
00846 ws_asm_link(compiler, ws_asm_load_const(compiler, expr->line, cindex));
00847 }
00848 break;
00849
00850 case WS_EXPR_CONST_STRING:
00851 if (expr->u.string.len == 0)
00852 ins = ws_asm_ins(compiler, expr->line, WS_ASM_CONST_ES);
00853 else {
00854 WsUInt16 cindex;
00855
00856 if (!ws_bc_add_const_utf8_string(compiler->bc, &cindex,
00857 expr->u.string.data,
00858 expr->u.string.len)) {
00859 ws_error_memory(compiler);
00860 return;
00861 }
00862 ins = ws_asm_load_const(compiler, expr->line, cindex);
00863 }
00864
00865 ws_asm_link(compiler, ins);
00866 break;
00867 }
00868 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 941 of file wsstree.c. References expr_alloc(), WsExpressionRec::left, WsExpressionRec::logical, WsExpressionRec::right, WsExpressionRec::type, WsExpressionRec::u, WS_EXPR_LOGICAL, WsCompilerPtr, and WsExpression. Referenced by yyparse(). 00943 {
00944 WsExpression *expr = expr_alloc(compiler, WS_EXPR_LOGICAL, line);
00945
00946 if (expr) {
00947 expr->u.logical.type = type;
00948 expr->u.logical.left = left;
00949 expr->u.logical.right = right;
00950 }
00951
00952 return expr;
00953 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1010 of file wsstree.c. References WsExpressionRec::addp, expr_alloc(), WsCompilerRec::pool_stree, WsExpressionRec::postfix_var, WsExpressionRec::u, WsExpressionRec::variable, ws_error_memory(), WS_EXPR_POSTFIX_VAR, ws_f_strdup(), ws_lexer_free_block(), WsCompilerPtr, and WsExpression. Referenced by yyparse(). 01012 {
01013 WsExpression *expr = expr_alloc(compiler, WS_EXPR_POSTFIX_VAR, line);
01014
01015 if (expr) {
01016 expr->u.postfix_var.addp = addp;
01017 expr->u.postfix_var.variable = ws_f_strdup(compiler->pool_stree,
01018 variable);
01019 if (expr->u.postfix_var.variable == NULL)
01020 ws_error_memory(compiler);
01021 }
01022 ws_lexer_free_block(compiler, variable);
01023
01024 return expr;
01025 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1051 of file wsstree.c. References expr_alloc(), WsCompilerRec::pool_stree, WsExpressionRec::symbol, WsExpressionRec::u, ws_error_memory(), WS_EXPR_SYMBOL, ws_f_strdup(), ws_lexer_free_block(), WsCompiler, and WsExpression. 01053 {
01054 WsExpression *expr = expr_alloc(compiler, WS_EXPR_SYMBOL, line);
01055
01056 if (expr) {
01057 expr->u.symbol = ws_f_strdup(compiler->pool_stree, identifier);
01058 if (expr->u.symbol == NULL)
01059 ws_error_memory(compiler);
01060 }
01061
01062 ws_lexer_free_block(compiler, identifier);
01063
01064 return expr;
01065 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 971 of file wsstree.c. References WsExpressionRec::expr, expr_alloc(), WsExpressionRec::integer, WsExpressionRec::sign, type, WsExpressionRec::type, WsExpressionRec::u, WsExpressionRec::unary, WS_ASM_UMINUS, WS_EXPR_UNARY, WsCompilerPtr, and WsExpression. Referenced by yyparse(). 00973 {
00974 WsExpression *expr;
00975
00976 /* Handle negative integers here as a special case of constant folding,
00977 * in order to get -2147483648 right. */
00978 if (type == WS_ASM_UMINUS && expression->type == WS_EXPR_CONST_INTEGER) {
00979 expression->u.integer.sign = - expression->u.integer.sign;
00980 return expression;
00981 }
00982
00983 expr = expr_alloc(compiler, WS_EXPR_UNARY, line);
00984 if (expr) {
00985 expr->u.unary.type = type;
00986 expr->u.unary.expr = expression;
00987 }
00988
00989 return expr;
00990 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 993 of file wsstree.c. References WsExpressionRec::addp, expr_alloc(), WsCompilerRec::pool_stree, WsExpressionRec::u, WsExpressionRec::unary_var, WsExpressionRec::variable, ws_error_memory(), WS_EXPR_UNARY_VAR, ws_f_strdup(), ws_lexer_free_block(), WsCompilerPtr, and WsExpression. Referenced by yyparse(). 00995 {
00996 WsExpression *expr = expr_alloc(compiler, WS_EXPR_UNARY_VAR, line);
00997
00998 if (expr) {
00999 expr->u.unary_var.addp = addp;
01000 expr->u.unary_var.variable = ws_f_strdup(compiler->pool_stree, variable);
01001 if (expr->u.unary_var.variable == NULL)
01002 ws_error_memory(compiler);
01003 }
01004 ws_lexer_free_block(compiler, variable);
01005
01006 return expr;
01007 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 93 of file wsstree.c. References WsFormalParmRec::line, WsFormalParmRec::name, WsCompilerRec::pool_stree, ws_error_memory(), ws_f_malloc(), WsCompilerPtr, and WsFormalParm. Referenced by yyparse(). 00095 {
00096 WsFormalParm *parm = ws_f_malloc(compiler->pool_stree, sizeof(*parm));
00097
00098 if (parm == NULL)
00099 ws_error_memory(compiler);
00100 else {
00101 parm->line = line;
00102 parm->name = name;
00103 }
00104
00105 return parm;
00106 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 343 of file wsstree.c. References WsFunctionRec::block, WsFunctionHashRec::defined, WsFunctionRec::externp, WsFunctionHashRec::findex, WsFunctionRec::findex, WsCompilerRec::functions, WsFunctionRec::line, WsFunctionRec::name, name, WsCompilerRec::num_extern_functions, WsCompilerRec::num_functions, WsCompilerRec::num_local_functions, WsFunctionRec::params, ws_error_memory(), ws_free(), ws_function_hash(), ws_realloc(), ws_src_error(), WsCompiler, WsFunction, WsFunctionHash, and WsList. 00345 {
00346 WsFunctionHash *hash;
00347 WsFunction *f = ws_realloc(compiler->functions,
00348 ((compiler->num_functions + 1)
00349 * sizeof(WsFunction)));
00350
00351 if (f == NULL) {
00352 ws_free(name);
00353 ws_error_memory(compiler);
00354 return;
00355 }
00356
00357 if (externp)
00358 compiler->num_extern_functions++;
00359 else
00360 compiler->num_local_functions++;
00361
00362 compiler->functions = f;
00363 f = &compiler->functions[compiler->num_functions];
00364
00365 f->findex = compiler->num_functions++;
00366
00367 f->externp = externp;
00368 f->name = name;
00369 f->line = line;
00370 f->params = params;
00371 f->block = block;
00372
00373 /* Update the function name hash. */
00374
00375 hash = ws_function_hash(compiler, name);
00376 if (hash == NULL) {
00377 ws_error_memory(compiler);
00378 return;
00379 }
00380
00381 if (hash->defined) {
00382 ws_src_error(compiler, line, "redefinition of `%s'", name);
00383 ws_src_error(compiler,
00384 compiler->functions[hash->findex].line,
00385 "`%s' previously defined here", name);
00386 return;
00387 }
00388
00389 hash->defined = WS_TRUE;
00390 hash->findex = f->findex;
00391 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 318 of file wsstree.c. References WsCompilerRec::functions_hash, name, ws_calloc(), ws_error_memory(), ws_free(), ws_hash_get(), ws_hash_put(), WsCompilerPtr, and WsFunctionHash. Referenced by compile_stream(), ws_expr_linearize(), ws_function(), and yyparse(). 00319 {
00320 WsFunctionHash *i = ws_hash_get(compiler->functions_hash, name);
00321
00322 if (i)
00323 return i;
00324
00325 /* Must create a new mapping. */
00326
00327 i = ws_calloc(1, sizeof(*i));
00328 if (i == NULL) {
00329 ws_error_memory(compiler);
00330 return NULL;
00331 }
00332
00333 if (!ws_hash_put(compiler->functions_hash, name, i)) {
00334 ws_free(i);
00335 ws_error_memory(compiler);
00336 return NULL;
00337 }
00338
00339 return i;
00340 }
|
Here is the call graph for this function:

|
|
Definition at line 312 of file wsstree.c. References function_hash_destructor(), ws_hash_create(), and WsHashPtr. Referenced by compile_stream(). 00313 {
00314 return ws_hash_create(function_hash_destructor, NULL);
00315 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 121 of file wsstree.c. References WsListItemRec::data, WsListRec::head, WsListItemRec::next, WsListRec::num_items, WsCompilerRec::pool_stree, WsListRec::tail, ws_error_memory(), ws_f_calloc(), WsCompiler, WsList, and WsListItem. 00122 {
00123 WsListItem *item;
00124
00125 if (list == NULL)
00126 /* A recovery code for previous memory allocation problems. */
00127 return;
00128
00129 item = ws_f_calloc(compiler->pool_stree, 1, sizeof(*item));
00130 if (item == NULL) {
00131 ws_error_memory(compiler);
00132 return;
00133 }
00134
00135 item->data = value;
00136
00137 if (list->tail) {
00138 list->tail->next = item;
00139 list->tail = item;
00140 } else
00141 list->head = list->tail = item;
00142
00143 list->num_items++;
00144 }
|
Here is the call graph for this function:

|
|
Definition at line 110 of file wsstree.c. References WsCompilerRec::pool_stree, ws_error_memory(), ws_f_calloc(), WsCompiler, and WsList. 00111 {
00112 WsList *list = ws_f_calloc(compiler->pool_stree, 1, sizeof(*list));
00113
00114 if (list == NULL)
00115 ws_error_memory(compiler);
00116
00117 return list;
00118 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 271 of file wsstree.c. References WsPragmaMetaBodyRec::property_name, ws_calloc(), ws_error_memory(), WsCompilerPtr, WsPragmaMetaBody, and WsUtf8String. Referenced by yyparse(). 00275 {
00276 WsPragmaMetaBody *mb = ws_calloc(1, sizeof(*mb));
00277
00278 if (mb == NULL) {
00279 ws_error_memory(compiler);
00280 return NULL;
00281 }
00282
00283 mb->property_name = property_name;
00284 mb->content = content;
00285 mb->scheme = scheme;
00286
00287 return mb;
00288 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 291 of file wsstree.c. References WsPragmaMetaBodyRec::content, WsPragmaMetaBodyRec::property_name, WsPragmaMetaBodyRec::scheme, ws_free(), ws_lexer_free_utf8(), WsCompilerPtr, and WsPragmaMetaBody. Referenced by yyparse(). 00292 {
00293 if (mb == NULL)
00294 return;
00295
00296 ws_lexer_free_utf8(compiler, mb->property_name);
00297 ws_lexer_free_utf8(compiler, mb->content);
00298 ws_lexer_free_utf8(compiler, mb->scheme);
00299
00300 ws_free(mb);
00301 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 220 of file wsstree.c. References WsCompilerRec::bc, WsUtf8StringRec::data, error(), WsUtf8StringRec::len, WsPragmaUseRec::line, WsCompilerRec::pragma_use_hash, ws_bc_add_const_utf8_string(), ws_calloc(), ws_error_memory(), ws_free(), ws_hash_get(), ws_hash_put(), ws_lexer_free_block(), ws_lexer_free_utf8(), ws_src_error(), WsCompilerPtr, WsPragmaUse, and WsUtf8String. Referenced by yyparse(). 00222 {
00223 WsPragmaUse *u = ws_calloc(1, sizeof(*u));
00224 WsPragmaUse *uold;
00225
00226 /* Do we already know this pragma? */
00227 uold = ws_hash_get(compiler->pragma_use_hash, identifier);
00228 if (uold) {
00229 ws_src_error(compiler, line, "redefinition of pragma `%s'", identifier);
00230 ws_src_error(compiler, uold->line, "`%s' previously defined here",
00231 identifier);
00232 goto error_cleanup;
00233 }
00234
00235 if (u == NULL)
00236 goto error;
00237
00238 u->line = line;
00239
00240 /* Insert the URL to the byte-code module. */
00241 if (!ws_bc_add_const_utf8_string(compiler->bc, &u->urlindex, url->data,
00242 url->len))
00243 goto error;
00244
00245 /* Add it to the use pragma hash. */
00246 if (!ws_hash_put(compiler->pragma_use_hash, identifier, u))
00247 goto error;
00248
00249 /* Cleanup. */
00250
00251 ws_lexer_free_block(compiler, identifier);
00252 ws_lexer_free_utf8(compiler, url);
00253
00254 return;
00255
00256 /* Error handling. */
00257
00258 error:
00259
00260 ws_error_memory(compiler);
00261
00262 error_cleanup:
00263
00264 ws_free(u);
00265 ws_lexer_free_block(compiler, identifier);
00266 ws_lexer_free_utf8(compiler, url);
00267 }
|
Here is the call graph for this function:

|
|
Definition at line 214 of file wsstree.c. References pragma_use_hash_destructor(), ws_hash_create(), and WsHashPtr. Referenced by compile_stream(). 00215 {
00216 return ws_hash_create(pragma_use_hash_destructor, NULL);
00217 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1389 of file wsstree.c. References WsStatementRec::block, stmt_alloc(), WsStatementRec::u, WS_STMT_BLOCK, WsCompiler, WsList, and WsStatement. 01391 {
01392 WsStatement *stmt = stmt_alloc(compiler, WS_STMT_BLOCK, fline, lline);
01393
01394 if (stmt)
01395 stmt->u.block = block;
01396
01397 return stmt;
01398 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1485 of file wsstree.c. References stmt_alloc(), WS_STMT_BREAK, WsCompiler, and WsStatement. 01486 {
01487 return stmt_alloc(compiler, WS_STMT_BREAK, line, line);
01488 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1479 of file wsstree.c. References stmt_alloc(), WS_STMT_CONTINUE, WsCompiler, and WsStatement. 01480 {
01481 return stmt_alloc(compiler, WS_STMT_CONTINUE, line, line);
01482 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1413 of file wsstree.c. References stmt_alloc(), WS_STMT_EMPTY, WsCompiler, and WsStatement. 01414 {
01415 return stmt_alloc(compiler, WS_STMT_EMPTY, line, line);
01416 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1419 of file wsstree.c. References WsStatementRec::expr, stmt_alloc(), WsStatementRec::u, WS_STMT_EXPR, WsCompiler, WsExpression, and WsStatement. 01421 {
01422 WsStatement *stmt = stmt_alloc(compiler, WS_STMT_EXPR, line, line);
01423
01424 if (stmt)
01425 stmt->u.expr = expr;
01426
01427 return stmt;
01428 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||
|
Definition at line 1447 of file wsstree.c. References WsStatementRec::e1, WsStatementRec::e2, WsStatementRec::e3, WsStatementRec::init, WsStatementRec::s_for, WsStatementRec::stmt, stmt_alloc(), WsStatementRec::u, WS_STMT_FOR, WsCompilerPtr, WsExpression, WsList, and WsStatement. Referenced by yyparse(). 01450 {
01451 WsStatement *stmt = stmt_alloc(compiler, WS_STMT_FOR, line, line);
01452
01453 if (stmt) {
01454 stmt->u.s_for.init = init;
01455 stmt->u.s_for.e1 = e1;
01456 stmt->u.s_for.e2 = e2;
01457 stmt->u.s_for.e3 = e3;
01458 stmt->u.s_for.stmt = stmt_body;
01459 }
01460
01461 return stmt;
01462 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 1431 of file wsstree.c. References WsStatementRec::expr, WsStatementRec::s_else, WsStatementRec::s_if, WsStatementRec::s_then, stmt_alloc(), WsStatementRec::u, WS_STMT_IF, WsCompiler, WsExpression, and WsStatement. 01434 {
01435 WsStatement *stmt = stmt_alloc(compiler, WS_STMT_IF, line, line);
01436
01437 if (stmt) {
01438 stmt->u.s_if.expr = expr;
01439 stmt->u.s_if.s_then = s_then;
01440 stmt->u.s_if.s_else = s_else;
01441 }
01442
01443 return stmt;
01444 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1157 of file wsstree.c. References WsStatementRec::block, WsCompilerRec::cont_break, WsListItemRec::data, WsStatementRec::e1, WsStatementRec::e2, WsStatementRec::e3, WsStatementRec::expr, WsStatementRec::first_line, WsListRec::head, WsStatementRec::init, WsContBreakRec::l_break, WsContBreakRec::l_cont, WsStatementRec::last_line, linearize_variable_init(), WsContBreakRec::next, WsListItemRec::next, WsCompilerRec::pool_stree, WsStatementRec::s_else, WsStatementRec::s_for, WsStatementRec::s_if, WsStatementRec::s_then, WsStatementRec::s_while, WsStatementRec::stmt, WsStatementRec::type, WsStatementRec::u, WsStatementRec::var, ws_asm_branch(), ws_asm_ins(), ws_asm_label(), ws_asm_link(), WS_ASM_P_JUMP, WS_ASM_P_TJUMP, WS_ASM_POP, WS_ASM_RETURN, WS_ASM_RETURN_ES, ws_error_memory(), ws_expr_linearize(), ws_f_calloc(), ws_src_error(), WS_STMT_BLOCK, WS_STMT_BREAK, WS_STMT_CONTINUE, WS_STMT_EMPTY, WS_STMT_EXPR, WS_STMT_FOR, WS_STMT_IF, ws_stmt_linearize(), WS_STMT_RETURN, WS_STMT_VARIABLE, WS_STMT_WHILE, WsAsmIns, WsCompiler, WsContBreak, WsListItem, and WsStatement. 01158 {
01159 WsListItem *li;
01160 WsAsmIns *ins;
01161
01162 switch (stmt->type) {
01163 case WS_STMT_BLOCK:
01164 for (li = stmt->u.block->head; li; li = li->next)
01165 ws_stmt_linearize(compiler, li->data);
01166 break;
01167
01168 case WS_STMT_VARIABLE:
01169 linearize_variable_init(compiler, stmt->u.var, stmt->first_line);
01170 break;
01171
01172 case WS_STMT_EMPTY:
01173 /* Nothing here. */
01174 break;
01175
01176 case WS_STMT_EXPR:
01177 ws_expr_linearize(compiler, stmt->u.expr);
01178
01179 /* Pop the expressions result from the stack. Otherwise loops
01180 could eventually cause stack overflows. */
01181 ws_asm_link(compiler, ws_asm_ins(compiler, stmt->last_line, WS_ASM_POP));
01182 break;
01183
01184 case WS_STMT_IF:
01185 {
01186 WsAsmIns *l_else = ws_asm_label(compiler,
01187 (stmt->u.s_if.s_else
01188 ? stmt->u.s_if.s_else->first_line
01189 : stmt->last_line));
01190 WsAsmIns *l_end = ws_asm_label(compiler, stmt->last_line);
01191
01192 /* Linearize the expression. */
01193 ws_expr_linearize(compiler, stmt->u.s_if.expr);
01194
01195 /* If the result is false, jump to the else-branch. */
01196 ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
01197 WS_ASM_P_TJUMP, l_else));
01198
01199 /* Else, execute the then-branch and jump to the end. */
01200 ws_stmt_linearize(compiler, stmt->u.s_if.s_then);
01201 ws_asm_link(compiler, ws_asm_branch(compiler, stmt->last_line,
01202 WS_ASM_P_JUMP, l_end));
01203
01204 /* Then else-branch. */
01205 ws_asm_link(compiler, l_else);
01206
01207 /* Linearize the else-branch if it is present. */
01208 if (stmt->u.s_if.s_else)
01209 ws_stmt_linearize(compiler, stmt->u.s_if.s_else);
01210
01211 /* Insert the end label. */
01212 ws_asm_link(compiler, l_end);
01213 }
01214 break;
01215
01216 case WS_STMT_FOR:
01217 {
01218 WsAsmIns *l_loop = ws_asm_label(compiler, stmt->first_line);
01219 WsAsmIns *l_cont = ws_asm_label(compiler, stmt->first_line);
01220 WsAsmIns *l_break = ws_asm_label(compiler, stmt->first_line);
01221 WsContBreak *cb;
01222
01223 /* Store the labels to the compiler. */
01224
01225 cb = ws_f_calloc(compiler->pool_stree, 1, sizeof(*cb));
01226 if (cb == NULL) {
01227 ws_error_memory(compiler);
01228 return;
01229 }
01230
01231 cb->next = compiler->cont_break;
01232 compiler->cont_break = cb;
01233
01234 cb->l_cont = l_cont;
01235 cb->l_break = l_break;
01236
01237 /* Linearize the possible init code. */
01238 if (stmt->u.s_for.init)
01239 linearize_variable_init(compiler, stmt->u.s_for.init,
01240 stmt->first_line);
01241 else if (stmt->u.s_for.e1) {
01242 /* Linearize the init. */
01243 ws_expr_linearize(compiler, stmt->u.s_for.e1);
01244
01245 /* Pop the result. */
01246 ws_asm_link(compiler, ws_asm_ins(compiler, stmt->first_line,
01247 WS_ASM_POP));
01248 }
01249
01250 /* Insert the loop label. */
01251 ws_asm_link(compiler, l_loop);
01252
01253 /* Linearize the condition. */
01254 if (stmt->u.s_for.e2) {
01255 ws_expr_linearize(compiler, stmt->u.s_for.e2);
01256
01257 /* If false, jump out. */
01258 ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
01259 WS_ASM_P_TJUMP, l_break));
01260 }
01261
01262 /* Linearize the body statement. */
01263 ws_stmt_linearize(compiler, stmt->u.s_for.stmt);
01264
01265 /* Link the continue label. */
01266 ws_asm_link(compiler, l_cont);
01267
01268 /* Linearize the update expression. */
01269 if (stmt->u.s_for.e3) {
01270 ws_expr_linearize(compiler, stmt->u.s_for.e3);
01271
01272 /* Pop the result. */
01273 ws_asm_link(compiler, ws_asm_ins(compiler, stmt->first_line,
01274 WS_ASM_POP));
01275 }
01276
01277 /* Jump to the loop label to check the condition. */
01278 ws_asm_link(compiler, ws_asm_branch(compiler, stmt->last_line,
01279 WS_ASM_P_JUMP, l_loop));
01280
01281 /* Insert the break label. */
01282 ws_asm_link(compiler, l_break);
01283
01284 /* Pop the cont-break block. */
01285 compiler->cont_break = compiler->cont_break->next;
01286 }
01287 break;
01288
01289 case WS_STMT_WHILE:
01290 {
01291 WsAsmIns *l_cont = ws_asm_label(compiler, stmt->first_line);
01292 WsAsmIns *l_break = ws_asm_label(compiler,
01293 stmt->u.s_while.stmt->last_line);
01294 WsContBreak *cb;
01295
01296 /* Store the labels to the compiler. */
01297
01298 cb = ws_f_calloc(compiler->pool_stree, 1, sizeof(*cb));
01299 if (cb == NULL) {
01300 ws_error_memory(compiler);
01301 return;
01302 }
01303
01304 cb->next = compiler->cont_break;
01305 compiler->cont_break = cb;
01306
01307 cb->l_cont = l_cont;
01308 cb->l_break = l_break;
01309
01310 /* Insert the continue label. */
01311 ws_asm_link(compiler, l_cont);
01312
01313 /* Linearize the expression. */
01314 ws_expr_linearize(compiler, stmt->u.s_while.expr);
01315
01316 /* If false, jump out. */
01317 ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
01318 WS_ASM_P_TJUMP, l_break));
01319
01320 /* Linearize the body statement. */
01321 ws_stmt_linearize(compiler, stmt->u.s_while.stmt);
01322
01323 /* And jump to the continue label to check the expression. */
01324 ws_asm_link(compiler, ws_asm_branch(compiler, stmt->last_line,
01325 WS_ASM_P_JUMP, l_cont));
01326
01327 /* Insert the break label. */
01328 ws_asm_link(compiler, l_break);
01329
01330 /* Pop the cont-break block. */
01331 compiler->cont_break = compiler->cont_break->next;
01332 }
01333 break;
01334
01335 case WS_STMT_CONTINUE:
01336 if (compiler->cont_break == NULL)
01337 ws_src_error(compiler, stmt->first_line,
01338 "continue statement not within a loop");
01339
01340 ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
01341 WS_ASM_P_JUMP,
01342 compiler->cont_break->l_cont));
01343 break;
01344
01345 case WS_STMT_BREAK:
01346 if (compiler->cont_break == NULL)
01347 ws_src_error(compiler, stmt->first_line,
01348 "break statement not within a loop");
01349
01350 ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
01351 WS_ASM_P_JUMP,
01352 compiler->cont_break->l_break));
01353 break;
01354
01355 case WS_STMT_RETURN:
01356 if (stmt->u.expr) {
01357 /* Linearize the return value and return it. */
01358 ws_expr_linearize(compiler, stmt->u.expr);
01359 ins = ws_asm_ins(compiler, stmt->first_line, WS_ASM_RETURN);
01360 } else
01361 /* Return an empty string. */
01362 ins = ws_asm_ins(compiler, stmt->first_line, WS_ASM_RETURN_ES);
01363
01364 ws_asm_link(compiler, ins);
01365 break;
01366 }
01367 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1491 of file wsstree.c. References WsStatementRec::expr, stmt_alloc(), WsStatementRec::u, WS_STMT_RETURN, WsCompilerPtr, WsExpression, and WsStatement. Referenced by yyparse(). 01493 {
01494 WsStatement *stmt = stmt_alloc(compiler, WS_STMT_RETURN, line, line);
01495
01496 if (stmt)
01497 stmt->u.expr = expr;
01498
01499 return stmt;
01500 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1401 of file wsstree.c. References stmt_alloc(), WsStatementRec::u, WsStatementRec::var, WS_STMT_VARIABLE, WsCompilerPtr, WsList, and WsStatement. Referenced by yyparse(). 01403 {
01404 WsStatement *stmt = stmt_alloc(compiler, WS_STMT_VARIABLE, line, line);
01405
01406 if (stmt)
01407 stmt->u.var = variables;
01408
01409 return stmt;
01410 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1465 of file wsstree.c. References WsStatementRec::expr, WsStatementRec::s_while, WsStatementRec::stmt, stmt_alloc(), WsStatementRec::u, WS_STMT_WHILE, WsCompiler, WsExpression, and WsStatement. 01467 {
01468 WsStatement *stmt = stmt_alloc(compiler, WS_STMT_WHILE, line, line);
01469
01470 if (stmt) {
01471 stmt->u.s_while.expr = expr;
01472 stmt->u.s_while.stmt = stmt_arg;
01473 }
01474
01475 return stmt;
01476 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 78 of file wsstree.c. References WsVarDecRec::expr, WsVarDecRec::name, WsCompilerRec::pool_stree, ws_error_memory(), ws_f_malloc(), WsCompilerPtr, WsExpression, and WsVarDec. Referenced by yyparse(). 00080 {
00081 WsVarDec *vardec = ws_f_malloc(compiler->pool_stree, sizeof(*vardec));
00082
00083 if (vardec == NULL)
00084 ws_error_memory(compiler);
00085 else {
00086 vardec->name = name;
00087 vardec->expr = expr;
00088 }
00089
00090 return vardec;
00091 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 160 of file wsstree.c. References WsNamespaceRec::line, name, WsCompilerRec::next_vindex, WsCompilerRec::variables_hash, WsNamespaceRec::vindex, ws_calloc(), ws_error_memory(), ws_free(), ws_hash_get(), ws_hash_put(), ws_src_error(), WsCompilerPtr, and WsNamespace. Referenced by compile_stream(), and linearize_variable_init(). 00162 {
00163 WsNamespace *ns;
00164
00165 /* Is the symbol already defined? */
00166 ns = ws_hash_get(compiler->variables_hash, name);
00167 if (ns) {
00168 ws_src_error(compiler, line, "redeclaration of `%s'", name);
00169 ws_src_error(compiler, ns->line, "`%s' previously declared here", name);
00170 return NULL;
00171 }
00172
00173 /* Can we still define more variables? */
00174 if (compiler->next_vindex > 255) {
00175 /* No we can't. */
00176 ws_src_error(compiler, line, "too many local variables");
00177 return NULL;
00178 }
00179
00180 ns = ws_calloc(1, sizeof(*ns));
00181 if (ns == NULL) {
00182 ws_error_memory(compiler);
00183 return NULL;
00184 }
00185
00186 ns->line = line;
00187 ns->vindex = compiler->next_vindex++;
00188
00189 if (!ws_hash_put(compiler->variables_hash, name, ns)) {
00190 ws_free(ns);
00191 ws_error_memory(compiler);
00192 return NULL;
00193 }
00194
00195 return ns;
00196 }
|
Here is the call graph for this function:

|
|
Definition at line 154 of file wsstree.c. References variable_hash_destructor(), ws_hash_create(), and WsHashPtr. Referenced by compile_stream(). 00155 {
00156 return ws_hash_create(variable_hash_destructor, NULL);
00157 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 199 of file wsstree.c. References name, WsCompilerRec::variables_hash, ws_hash_get(), WsCompilerPtr, and WsNamespace. Referenced by ws_expr_linearize(). 00200 {
00201 return ws_hash_get(compiler->variables_hash, name);
00202 }
|
Here is the call graph for this function:
