Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

wsstree.c File Reference

#include "wsint.h"
#include "wsgram.h"

Include dependency graph for wsstree.c:

Include dependency graph

Go to the source code of this file.

Functions

WsVarDecws_variable_declaration (WsCompilerPtr compiler, char *name, WsExpression *expr)
WsFormalParmws_formal_parameter (WsCompilerPtr compiler, WsUInt32 line, char *name)
WsListws_list_new (WsCompiler *compiler)
void ws_list_append (WsCompiler *compiler, WsList *list, void *value)
void variable_hash_destructor (void *item, void *context)
WsHashPtr ws_variable_hash_create (void)
WsNamespacews_variable_define (WsCompilerPtr compiler, WsUInt32 line, WsBool variablep, char *name)
WsNamespacews_variable_lookup (WsCompilerPtr compiler, char *name)
void pragma_use_hash_destructor (void *item, void *context)
WsHashPtr ws_pragma_use_hash_create (void)
void ws_pragma_use (WsCompilerPtr compiler, WsUInt32 line, char *identifier, WsUtf8String *url)
WsPragmaMetaBodyws_pragma_meta_body (WsCompilerPtr compiler, WsUtf8String *property_name, WsUtf8String *content, WsUtf8String *scheme)
void ws_pragma_meta_body_free (WsCompilerPtr compiler, WsPragmaMetaBody *mb)
void function_hash_destructor (void *item, void *context)
WsHashPtr ws_function_hash_create (void)
WsFunctionHashws_function_hash (WsCompilerPtr compiler, char *name)
void ws_function (WsCompiler *compiler, WsBool externp, char *name, WsUInt32 line, WsList *params, WsList *block)
void ws_expr_linearize (WsCompiler *compiler, WsExpression *expr)
WsExpressionexpr_alloc (WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
WsExpressionws_expr_comma (WsCompilerPtr compiler, WsUInt32 line, WsExpression *left, WsExpression *right)
WsExpressionws_expr_assign (WsCompilerPtr compiler, WsUInt32 line, char *identifier, int op, WsExpression *expr)
WsExpressionws_expr_conditional (WsCompilerPtr compiler, WsUInt32 line, WsExpression *e_cond, WsExpression *e_then, WsExpression *e_else)
WsExpressionws_expr_logical (WsCompilerPtr compiler, WsUInt32 line, int type, WsExpression *left, WsExpression *right)
WsExpressionws_expr_binary (WsCompilerPtr compiler, WsUInt32 line, int type, WsExpression *left, WsExpression *right)
WsExpressionws_expr_unary (WsCompilerPtr compiler, WsUInt32 line, int type, WsExpression *expression)
WsExpressionws_expr_unary_var (WsCompilerPtr compiler, WsUInt32 line, WsBool addp, char *variable)
WsExpressionws_expr_postfix_var (WsCompilerPtr compiler, WsUInt32 line, WsBool addp, char *variable)
WsExpressionws_expr_call (WsCompiler *compiler, WsUInt32 line, int type, char *base, char *name, WsList *arguments)
WsExpressionws_expr_symbol (WsCompiler *compiler, WsUInt32 line, char *identifier)
WsExpressionws_expr_const_invalid (WsCompiler *compiler, WsUInt32 line)
WsExpressionws_expr_const_true (WsCompiler *compiler, WsUInt32 line)
WsExpressionws_expr_const_false (WsCompiler *compiler, WsUInt32 line)
WsExpressionws_expr_const_integer (WsCompiler *compiler, WsUInt32 line, WsUInt32 ival)
WsExpressionws_expr_const_float (WsCompiler *compiler, WsUInt32 line, WsFloat fval)
WsExpressionws_expr_const_string (WsCompiler *compiler, WsUInt32 line, WsUtf8String *string)
void linearize_variable_init (WsCompiler *compiler, WsList *list, WsUInt32 line)
void ws_stmt_linearize (WsCompiler *compiler, WsStatement *stmt)
WsStatementstmt_alloc (WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
WsStatementws_stmt_block (WsCompiler *compiler, WsUInt32 fline, WsUInt32 lline, WsList *block)
WsStatementws_stmt_variable (WsCompilerPtr compiler, WsUInt32 line, WsList *variables)
WsStatementws_stmt_empty (WsCompiler *compiler, WsUInt32 line)
WsStatementws_stmt_expr (WsCompiler *compiler, WsUInt32 line, WsExpression *expr)
WsStatementws_stmt_if (WsCompiler *compiler, WsUInt32 line, WsExpression *expr, WsStatement *s_then, WsStatement *s_else)
WsStatementws_stmt_for (WsCompilerPtr compiler, WsUInt32 line, WsList *init, WsExpression *e1, WsExpression *e2, WsExpression *e3, WsStatement *stmt_body)
WsStatementws_stmt_while (WsCompiler *compiler, WsUInt32 line, WsExpression *expr, WsStatement *stmt_arg)
WsStatementws_stmt_continue (WsCompiler *compiler, WsUInt32 line)
WsStatementws_stmt_break (WsCompiler *compiler, WsUInt32 line)
WsStatementws_stmt_return (WsCompilerPtr compiler, WsUInt32 line, WsExpression *expr)


Function Documentation

WsExpression* expr_alloc WsCompiler compiler,
WsExpressionType  type,
WsUInt32  line
[static]
 

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:

void function_hash_destructor void *  item,
void *  context
[static]
 

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:

void linearize_variable_init WsCompiler compiler,
WsList list,
WsUInt32  line
[static]
 

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:

void pragma_use_hash_destructor void *  item,
void *  context
[static]
 

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:

WsStatement* stmt_alloc WsCompiler compiler,
WsStatementType  type,
WsUInt32  first_line,
WsUInt32  last_line
[static]
 

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:

void variable_hash_destructor void *  item,
void *  context
[static]
 

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:

WsExpression* ws_expr_assign WsCompilerPtr  compiler,
WsUInt32  line,
char *  identifier,
int  op,
WsExpression expr
 

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:

WsExpression* ws_expr_binary WsCompilerPtr  compiler,
WsUInt32  line,
int  type,
WsExpression left,
WsExpression right
 

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:

WsExpression* ws_expr_call WsCompiler compiler,
WsUInt32  line,
int  type,
char *  base,
char *  name,
WsList arguments
 

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:

WsExpression* ws_expr_comma WsCompilerPtr  compiler,
WsUInt32  line,
WsExpression left,
WsExpression right
 

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:

WsExpression* ws_expr_conditional WsCompilerPtr  compiler,
WsUInt32  line,
WsExpression e_cond,
WsExpression e_then,
WsExpression e_else
 

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:

WsExpression* ws_expr_const_false WsCompiler compiler,
WsUInt32  line
 

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:

WsExpression* ws_expr_const_float WsCompiler compiler,
WsUInt32  line,
WsFloat  fval
 

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:

WsExpression* ws_expr_const_integer WsCompiler compiler,
WsUInt32  line,
WsUInt32  ival
 

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:

WsExpression* ws_expr_const_invalid WsCompiler compiler,
WsUInt32  line
 

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:

WsExpression* ws_expr_const_string WsCompiler compiler,
WsUInt32  line,
WsUtf8String string
 

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:

WsExpression* ws_expr_const_true WsCompiler compiler,
WsUInt32  line
 

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:

void ws_expr_linearize WsCompiler compiler,
WsExpression expr
 

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:

WsExpression* ws_expr_logical WsCompilerPtr  compiler,
WsUInt32  line,
int  type,
WsExpression left,
WsExpression right
 

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:

WsExpression* ws_expr_postfix_var WsCompilerPtr  compiler,
WsUInt32  line,
WsBool  addp,
char *  variable
 

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:

WsExpression* ws_expr_symbol WsCompiler compiler,
WsUInt32  line,
char *  identifier
 

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:

WsExpression* ws_expr_unary WsCompilerPtr  compiler,
WsUInt32  line,
int  type,
WsExpression expression
 

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:

WsExpression* ws_expr_unary_var WsCompilerPtr  compiler,
WsUInt32  line,
WsBool  addp,
char *  variable
 

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:

WsFormalParm* ws_formal_parameter WsCompilerPtr  compiler,
WsUInt32  line,
char *  name
 

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:

void ws_function WsCompiler compiler,
WsBool  externp,
char *  name,
WsUInt32  line,
WsList params,
WsList block
 

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:

WsFunctionHash* ws_function_hash WsCompilerPtr  compiler,
char *  name
 

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:

WsHashPtr ws_function_hash_create void   ) 
 

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:

void ws_list_append WsCompiler compiler,
WsList list,
void *  value
 

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:

WsList* ws_list_new WsCompiler compiler  ) 
 

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:

WsPragmaMetaBody* ws_pragma_meta_body WsCompilerPtr  compiler,
WsUtf8String property_name,
WsUtf8String content,
WsUtf8String scheme
 

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:

void ws_pragma_meta_body_free WsCompilerPtr  compiler,
WsPragmaMetaBody mb
 

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:

void ws_pragma_use WsCompilerPtr  compiler,
WsUInt32  line,
char *  identifier,
WsUtf8String url
 

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:

WsHashPtr ws_pragma_use_hash_create void   ) 
 

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:

WsStatement* ws_stmt_block WsCompiler compiler,
WsUInt32  fline,
WsUInt32  lline,
WsList block
 

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:

WsStatement* ws_stmt_break WsCompiler compiler,
WsUInt32  line
 

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:

WsStatement* ws_stmt_continue WsCompiler compiler,
WsUInt32  line
 

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:

WsStatement* ws_stmt_empty WsCompiler compiler,
WsUInt32  line
 

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:

WsStatement* ws_stmt_expr WsCompiler compiler,
WsUInt32  line,
WsExpression expr
 

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:

WsStatement* ws_stmt_for WsCompilerPtr  compiler,
WsUInt32  line,
WsList init,
WsExpression e1,
WsExpression e2,
WsExpression e3,
WsStatement stmt_body
 

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:

WsStatement* ws_stmt_if WsCompiler compiler,
WsUInt32  line,
WsExpression expr,
WsStatement s_then,
WsStatement s_else
 

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:

void ws_stmt_linearize WsCompiler compiler,
WsStatement stmt
 

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:

WsStatement* ws_stmt_return WsCompilerPtr  compiler,
WsUInt32  line,
WsExpression expr
 

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:

WsStatement* ws_stmt_variable WsCompilerPtr  compiler,
WsUInt32  line,
WsList variables
 

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:

WsStatement* ws_stmt_while WsCompiler compiler,
WsUInt32  line,
WsExpression expr,
WsStatement stmt_arg
 

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:

WsVarDec* ws_variable_declaration WsCompilerPtr  compiler,
char *  name,
WsExpression expr
 

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:

WsNamespace* ws_variable_define WsCompilerPtr  compiler,
WsUInt32  line,
WsBool  variablep,
char *  name
 

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:

WsHashPtr ws_variable_hash_create void   ) 
 

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:

WsNamespace* ws_variable_lookup WsCompilerPtr  compiler,
char *  name
 

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:

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.