Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
wsstree.c File Reference
#include "wsint.h"
#include "wsgram.h"

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)
 
static 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)
 
static 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)
 
static 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)
 
static 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)
 
static void linearize_variable_init (WsCompiler *compiler, WsList *list, WsUInt32 line)
 
void ws_stmt_linearize (WsCompiler *compiler, WsStatement *stmt)
 
static 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

static WsExpression* expr_alloc ( WsCompiler compiler,
WsExpressionType  type,
WsUInt32  line 
)
static

Definition at line 873 of file wsstree.c.

References WsExpressionRec::line, WsCompilerRec::pool_stree, type, WsExpressionRec::type, ws_error_memory(), and ws_f_calloc().

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().

875 {
876  WsExpression *expr = ws_f_calloc(compiler->pool_stree, 1, sizeof(*expr));
877 
878  if (expr == NULL)
879  ws_error_memory(compiler);
880  else {
881  expr->type = type;
882  expr->line = line;
883  }
884 
885  return expr;
886 }
int type
Definition: smsc_cimd2.c:215
WsUInt32 line
Definition: wsstree.h:275
void * ws_f_calloc(WsFastMalloc *pool, size_t num, size_t size)
Definition: wsfalloc.c:150
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsExpressionType type
Definition: wsstree.h:274
static 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().

307 {
308  ws_free(item);
309 }
void ws_free(void *ptr)
Definition: wsalloc.c:139
static 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, and ws_variable_define().

Referenced by ws_stmt_linearize().

1135 {
1136  WsNamespace *ns;
1137  WsListItem *li;
1138 
1139  /* For each variable, declared with this list. */
1140  for (li = list->head; li; li = li->next) {
1141  WsVarDec *vardec = li->data;
1142 
1143  ns = ws_variable_define(compiler, line, WS_TRUE, vardec->name);
1144  if (ns && vardec->expr) {
1145  ws_expr_linearize(compiler, vardec->expr);
1146 
1147  /* Emit an instruction to store the initialization
1148  value to the variable. */
1149  ws_asm_link(compiler,
1150  ws_asm_variable(compiler, line, WS_ASM_P_STORE_VAR,
1151  ns->vindex));
1152  }
1153  }
1154 }
void ws_asm_link(WsCompiler *compiler, WsAsmIns *ins)
Definition: wsasm.c:93
struct WsListItemRec * next
Definition: wsstree.h:79
Definition: wsint.h:131
WsUInt8 vindex
Definition: wsstree.h:119
void ws_expr_linearize(WsCompiler *compiler, WsExpression *expr)
Definition: wsstree.c:395
WsListItem * head
Definition: wsstree.h:88
void * data
Definition: wsstree.h:80
WsAsmIns * ws_asm_variable(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst, WsUInt8 vindex)
Definition: wsasm.c:896
WsExpression * expr
Definition: wsstree.h:480
#define WS_ASM_P_STORE_VAR
Definition: wsasm.h:232
WsNamespace * ws_variable_define(WsCompilerPtr compiler, WsUInt32 line, WsBool variablep, char *name)
Definition: wsstree.c:160
char * name
Definition: wsstree.h:479
static 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().

209 {
210  ws_free(item);
211 }
void ws_free(void *ptr)
Definition: wsalloc.c:139
static 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, type, WsStatementRec::type, ws_error_memory(), and ws_f_calloc().

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().

1374 {
1375  WsStatement *stmt = ws_f_calloc(compiler->pool_stree, 1, sizeof(*stmt));
1376 
1377  if (stmt == NULL)
1378  ws_error_memory(compiler);
1379  else {
1380  stmt->type = type;
1381  stmt->first_line = first_line;
1382  stmt->last_line = last_line;
1383  }
1384 
1385  return stmt;
1386 }
int type
Definition: smsc_cimd2.c:215
WsUInt32 last_line
Definition: wsstree.h:525
WsUInt32 first_line
Definition: wsstree.h:524
WsStatementType type
Definition: wsstree.h:523
void * ws_f_calloc(WsFastMalloc *pool, size_t num, size_t size)
Definition: wsfalloc.c:150
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
static 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().

149 {
150  ws_free(item);
151 }
void ws_free(void *ptr)
Definition: wsalloc.c:139
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, expr_alloc(), WsCompilerRec::pool_stree, WsExpressionRec::u, ws_error_memory(), WS_EXPR_ASSIGN, ws_f_strdup(), and ws_lexer_free_block().

Referenced by yyparse().

905 {
906  WsExpression *e = expr_alloc(compiler, WS_EXPR_ASSIGN, line);
907 
908  if (e) {
909  e->u.assign.identifier = ws_f_strdup(compiler->pool_stree, identifier);
910  if (e->u.assign.identifier == NULL)
911  ws_error_memory(compiler);
912 
913  e->u.assign.op = op;
914  e->u.assign.expr = expr;
915  }
916 
917  /* Free the identifier symbol since it allocated from the system
918  heap. */
919  ws_lexer_free_block(compiler, identifier);
920 
921  return e;
922 }
void ws_lexer_free_block(WsCompiler *compiler, void *ptr)
Definition: ws.c:281
void * ws_f_strdup(WsFastMalloc *pool, const char *str)
Definition: wsfalloc.c:177
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
WsFastMalloc * pool_stree
Definition: wsint.h:204
struct WsExpressionRec::@118::@120 assign
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
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(), type, WsExpressionRec::u, and WS_EXPR_BINARY.

Referenced by yyparse().

958 {
959  WsExpression *expr = expr_alloc(compiler, WS_EXPR_BINARY, line);
960 
961  if (expr) {
962  expr->u.binary.type = type;
963  expr->u.binary.left = left;
964  expr->u.binary.right = right;
965  }
966 
967  return expr;
968 }
int type
Definition: smsc_cimd2.c:215
struct WsExpressionRec::@118::@123 binary
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
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::call, expr_alloc(), WsCompilerRec::pool_stree, type, WsExpressionRec::u, ws_error_memory(), WS_EXPR_CALL, ws_f_strdup(), and ws_lexer_free_block().

Referenced by yyparse().

1030 {
1031  WsExpression *expr = expr_alloc(compiler, WS_EXPR_CALL, line);
1032 
1033  if (expr) {
1034  expr->u.call.type = type;
1035  expr->u.call.base = ws_f_strdup(compiler->pool_stree, base);
1036  expr->u.call.name = ws_f_strdup(compiler->pool_stree, name);
1037  expr->u.call.arguments = arguments;
1038 
1039  if ((base && expr->u.call.base == NULL)
1040  || (name && expr->u.call.name == NULL))
1041  ws_error_memory(compiler);
1042  }
1043 
1044  ws_lexer_free_block(compiler, base);
1045  ws_lexer_free_block(compiler, name);
1046 
1047  return expr;
1048 }
int type
Definition: smsc_cimd2.c:215
void ws_lexer_free_block(WsCompiler *compiler, void *ptr)
Definition: ws.c:281
void * ws_f_strdup(WsFastMalloc *pool, const char *str)
Definition: wsfalloc.c:177
char * name
Definition: smsc_cimd2.c:212
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
WsFastMalloc * pool_stree
Definition: wsint.h:204
struct WsExpressionRec::@118::@127 call
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
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::u, and WS_EXPR_COMMA.

Referenced by yyparse().

891 {
892  WsExpression *expr = expr_alloc(compiler, WS_EXPR_COMMA, line);
893 
894  if (expr) {
895  expr->u.comma.left = left;
896  expr->u.comma.right = right;
897  }
898 
899  return expr;
900 }
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
struct WsExpressionRec::@118::@119 comma
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, expr_alloc(), WsExpressionRec::u, and WS_EXPR_CONDITIONAL.

Referenced by yyparse().

928 {
929  WsExpression *e = expr_alloc(compiler, WS_EXPR_CONDITIONAL, line);
930 
931  if (e) {
932  e->u.conditional.e_cond = e_cond;
933  e->u.conditional.e_then = e_then;
934  e->u.conditional.e_else = e_else;
935  }
936 
937  return e;
938 }
struct WsExpressionRec::@118::@121 conditional
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
WsExpression* ws_expr_const_false ( WsCompiler compiler,
WsUInt32  line 
)

Definition at line 1080 of file wsstree.c.

References expr_alloc(), and WS_EXPR_CONST_FALSE.

Referenced by yyparse().

1081 {
1082  return expr_alloc(compiler, WS_EXPR_CONST_FALSE, line);
1083 }
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
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, and WS_EXPR_CONST_FLOAT.

Referenced by yyparse().

1102 {
1103  WsExpression *expr = expr_alloc(compiler, WS_EXPR_CONST_FLOAT, line);
1104 
1105  if (expr)
1106  expr->u.fval = fval;
1107 
1108  return expr;
1109 }
WsFloat fval
Definition: wsstree.h:384
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
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::u, and WS_EXPR_CONST_INTEGER.

Referenced by yyparse().

1088 {
1089  WsExpression *expr = expr_alloc(compiler, WS_EXPR_CONST_INTEGER, line);
1090 
1091  if (expr) {
1092  expr->u.integer.sign = 1;
1093  expr->u.integer.ival = ival;
1094  }
1095 
1096  return expr;
1097 }
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
struct WsExpressionRec::@118::@128 integer
WsExpression* ws_expr_const_invalid ( WsCompiler compiler,
WsUInt32  line 
)

Definition at line 1068 of file wsstree.c.

References expr_alloc(), and WS_EXPR_CONST_INVALID.

Referenced by yyparse().

1069 {
1070  return expr_alloc(compiler, WS_EXPR_CONST_INVALID, line);
1071 }
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
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, WsExpressionRec::string, WsExpressionRec::u, ws_error_memory(), WS_EXPR_CONST_STRING, ws_f_memdup(), and ws_lexer_free_utf8().

Referenced by yyparse().

1114 {
1115  WsExpression *expr = expr_alloc(compiler, WS_EXPR_CONST_STRING, line);
1116 
1117  if (expr) {
1118  expr->u.string.len = string->len;
1119  expr->u.string.data = ws_f_memdup(compiler->pool_stree,
1120  string->data, string->len);
1121  if (expr->u.string.data == NULL)
1122  ws_error_memory(compiler);
1123  }
1124 
1125  ws_lexer_free_utf8(compiler, string);
1126 
1127  return expr;
1128 }
size_t len
Definition: wsutf8.h:81
unsigned char * data
Definition: wsutf8.h:84
void * ws_f_memdup(WsFastMalloc *pool, const void *ptr, size_t size)
Definition: wsfalloc.c:163
WsUtf8String string
Definition: wsstree.h:385
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_lexer_free_utf8(WsCompiler *compiler, WsUtf8String *string)
Definition: ws.c:305
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsExpression* ws_expr_const_true ( WsCompiler compiler,
WsUInt32  line 
)

Definition at line 1074 of file wsstree.c.

References expr_alloc(), and WS_EXPR_CONST_TRUE.

Referenced by yyparse().

1075 {
1076  return expr_alloc(compiler, WS_EXPR_CONST_TRUE, line);
1077 }
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
void ws_expr_linearize ( WsCompiler compiler,
WsExpression expr 
)

Definition at line 395 of file wsstree.c.

References WsExpressionRec::assign, WsCompilerRec::bc, WsExpressionRec::binary, WsExpressionRec::call, WsExpressionRec::comma, WsExpressionRec::conditional, WsListItemRec::data, WsUtf8StringRec::data, WsFunctionHashRec::defined, WsFunctionHashRec::findex, WsCompilerRec::functions, WsExpressionRec::fval, WsExpressionRec::integer, WsUtf8StringRec::len, WsExpressionRec::line, WsExpressionRec::logical, WsListItemRec::next, WsListRec::num_items, WsFunctionRec::params, WsExpressionRec::postfix_var, WsCompilerRec::pragma_use_hash, 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, 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_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(), and ws_variable_lookup().

Referenced by linearize_variable_init(), and ws_stmt_linearize().

396 {
397  WsListItem *li;
398  WsAsmIns *ins;
399 
400  switch (expr->type) {
401  case WS_EXPR_COMMA:
402  /* Linearize left. */
403  ws_expr_linearize(compiler, expr->u.comma.left);
404 
405  /* Pop its result. */
406  ws_asm_link(compiler, ws_asm_ins(compiler, expr->line, WS_ASM_POP));
407 
408  /* Linearize right */
409  ws_expr_linearize(compiler, expr->u.comma.right);
410  break;
411 
412  case WS_EXPR_ASSIGN:
413  {
414  WsNamespace *ns = ws_variable_lookup(compiler,
415  expr->u.assign.identifier);
416 
417  if (ns == NULL) {
418  /* Unknown identifier. */
419  ws_src_error(compiler, expr->line, "unknown variable `%s'",
420  expr->u.symbol);
421  return;
422  }
423 
424  if (expr->u.assign.op == '=') {
425  /* Evaluate the expression. */
426  ws_expr_linearize(compiler, expr->u.assign.expr);
427 
428  /* Store the value to the variable. */
429  ws_asm_link(compiler,
430  ws_asm_variable(compiler, expr->line,
431  WS_ASM_P_STORE_VAR, ns->vindex));
432  } else if (expr->u.assign.op == tADDA) {
433  /* Linearize the expression. */
434  ws_expr_linearize(compiler, expr->u.assign.expr);
435 
436  /* Add it to the variable. */
437  ws_asm_link(compiler,
438  ws_asm_variable(compiler, expr->line,
439  WS_ASM_ADD_ASG, ns->vindex));
440  } else if (expr->u.assign.op == tSUBA) {
441  /* Linearize the expression. */
442  ws_expr_linearize(compiler, expr->u.assign.expr);
443 
444  /* Substract it from the variable. */
445  ws_asm_link(compiler,
446  ws_asm_variable(compiler, expr->line,
447  WS_ASM_SUB_ASG, ns->vindex));
448  } else {
449  /* Load the old value from the variable. */
450  ws_asm_link(compiler,
451  ws_asm_variable(compiler, expr->line,
452  WS_ASM_P_LOAD_VAR, ns->vindex));
453 
454  /* Evaluate the expression. */
455  ws_expr_linearize(compiler, expr->u.assign.expr);
456 
457  /* Perform the operand. */
458  ins = NULL;
459  switch (expr->u.assign.op) {
460  case tMULA:
461  ins = ws_asm_ins(compiler, expr->line, WS_ASM_MUL);
462  break;
463 
464  case tDIVA:
465  ins = ws_asm_ins(compiler, expr->line, WS_ASM_DIV);
466  break;
467 
468  case tREMA:
469  ins = ws_asm_ins(compiler, expr->line, WS_ASM_REM);
470  break;
471 
472  case tADDA:
473  ins = ws_asm_ins(compiler, expr->line, WS_ASM_ADD);
474  break;
475 
476  case tSUBA:
477  ins = ws_asm_ins(compiler, expr->line, WS_ASM_SUB);
478  break;
479 
480  case tLSHIFTA:
481  ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_LSHIFT);
482  break;
483 
484  case tRSSHIFTA:
485  ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_RSSHIFT);
486  break;
487 
488  case tRSZSHIFTA:
489  ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_RSZSHIFT);
490  break;
491 
492  case tANDA:
493  ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_AND);
494  break;
495 
496  case tXORA:
497  ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_XOR);
498  break;
499 
500  case tORA:
501  ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_OR);
502  break;
503 
504  case tIDIVA:
505  ins = ws_asm_ins(compiler, expr->line, WS_ASM_IDIV);
506  break;
507 
508  default:
509  ws_fatal("ws_expr_linearize(): unknown assignment operand %x",
510  expr->u.assign.op);
511  break;
512  }
513  ws_asm_link(compiler, ins);
514 
515  /* Store the value to the variable. */
516  ws_asm_link(compiler,
517  ws_asm_variable(compiler, expr->line,
518  WS_ASM_P_STORE_VAR, ns->vindex));
519  }
520  /* The value of the assignment expression is the value
521  assigned. So, we must load the value from the variable.
522  This would also be a good place for the `dup' operand but
523  we lose since we don't have it. */
524  ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,
525  WS_ASM_P_LOAD_VAR, ns->vindex));
526  }
527  break;
528 
529  case WS_EXPR_CONDITIONAL:
530  {
531  WsAsmIns *l_else = ws_asm_label(compiler, expr->line);
532  WsAsmIns *l_end = ws_asm_label(compiler, expr->line);
533 
534  /* Linearize condition. */
535  ws_expr_linearize(compiler, expr->u.conditional.e_cond);
536 
537  /* If the result if false, jump to the else-branch. */
538  ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,
539  WS_ASM_P_TJUMP, l_else));
540 
541  /* Linearize the then-expression and jump out. */
542  ws_expr_linearize(compiler, expr->u.conditional.e_then);
543  ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,
544  WS_ASM_P_JUMP, l_end));
545 
546  /* The else-branch. */
547  ws_asm_link(compiler, l_else);
548  ws_expr_linearize(compiler, expr->u.conditional.e_else);
549 
550  /* Insert the end label. */
551  ws_asm_link(compiler, l_end);
552  }
553  break;
554 
555  case WS_EXPR_LOGICAL:
556  {
557  WsAsmIns *l_out = ws_asm_label(compiler, expr->line);
558 
559  /* Linearize the left-hand size expression. */
560  ws_expr_linearize(compiler, expr->u.logical.left);
561 
562  /* Short-circuit check. The type of the logical expression is
563  the short-circuit byte-code operand. */
564  ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
565  expr->u.logical.type));
566  ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,
567  WS_ASM_P_TJUMP, l_out));
568 
569  /* Linearize the right-hand size expression. */
570  ws_expr_linearize(compiler, expr->u.logical.right);
571 
572  /* The result of a logical expression should be boolean.
573  * Control statements do automatic conversion, but typeof()
574  * does not. */
575  ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
576  WS_ASM_TOBOOL));
577 
578  /* Insert the end label. */
579  ws_asm_link(compiler, l_out);
580  }
581  break;
582 
583  case WS_EXPR_BINARY:
584  /* Linearize left and right. */
585  ws_expr_linearize(compiler, expr->u.binary.left);
586  ws_expr_linearize(compiler, expr->u.binary.right);
587 
588  /* The type of the binary expression is the byte-code opcode. */
589  ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
590  expr->u.binary.type));
591  break;
592 
593  case WS_EXPR_UNARY:
594  /* Linearize the expression. */
595  ws_expr_linearize(compiler, expr->u.unary.expr);
596 
597  /* The type of the unary expression is the byte-code opcode. */
598  ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
599  expr->u.unary.type));
600  break;
601 
602  case WS_EXPR_UNARY_VAR:
603  {
604  WsNamespace *ns = ws_variable_lookup(compiler,
605  expr->u.unary_var.variable);
606  if (ns == NULL) {
607  /* An unknown identifier. */
608  ws_src_error(compiler, expr->line, "unknown variable `%s'",
609  expr->u.unary_var.variable);
610  return;
611  }
612 
613  /* First, do the operation. */
614  if (expr->u.unary_var.addp)
615  ws_asm_link(compiler,
616  ws_asm_variable(compiler, expr->line, WS_ASM_P_INCR_VAR,
617  ns->vindex));
618  else
619  ws_asm_link(compiler,
620  ws_asm_variable(compiler, expr->line, WS_ASM_DECR_VAR,
621  ns->vindex));
622 
623  /* Second, load the new value of the variable. */
624  ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,
625  WS_ASM_P_LOAD_VAR, ns->vindex));
626  }
627  break;
628 
629  case WS_EXPR_POSTFIX_VAR:
630  {
631  WsNamespace *ns = ws_variable_lookup(compiler,
632  expr->u.postfix_var.variable);
633  if (ns == NULL) {
634  /* An unknown identifier. */
635  ws_src_error(compiler, expr->line, "unknown variable `%s'",
636  expr->u.postfix_var.variable);
637  return;
638  }
639 
640  /* First, load the old value of the variable. */
641  ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,
642  WS_ASM_P_LOAD_VAR, ns->vindex));
643 
644  /* Second, do the operation. */
645  if (expr->u.unary_var.addp)
646  ws_asm_link(compiler,
647  ws_asm_variable(compiler, expr->line, WS_ASM_P_INCR_VAR,
648  ns->vindex));
649  else
650  ws_asm_link(compiler,
651  ws_asm_variable(compiler, expr->line, WS_ASM_DECR_VAR,
652  ns->vindex));
653  }
654  break;
655 
656  case WS_EXPR_CALL:
657  /* First, evaluate the arguments. */
658  for (li = expr->u.call.arguments->head; li; li = li->next)
659  ws_expr_linearize(compiler, li->data);
660 
661  /* Second, emit the call instruction. */
662  switch (expr->u.call.type) {
663  case ' ': /* LocalScriptFunctionCall */
664  {
665  WsFunctionHash *f = ws_function_hash(compiler, expr->u.call.name);
666 
667  if (f == NULL || !f->defined)
668  {
669  ws_src_error(compiler, expr->line,
670  "unknown local function `%s'",
671  expr->u.call.name);
672  return;
673  }
674 
675  /* Check that the function is called with correct amount
676  of arguments. */
677  if (expr->u.call.arguments->num_items
678  != compiler->functions[f->findex].params->num_items)
679  {
680  ws_src_error(compiler, expr->line,
681  "invalid amount of arguments for `%s': "
682  "expected %u, got %u",
683  expr->u.call.name,
684  compiler->functions[f->findex].params->num_items,
685  expr->u.call.arguments->num_items);
686  return;
687  }
688 
689  /* Emit assembler. */
690  ws_asm_link(compiler, ws_asm_call(compiler, expr->line,
691  f->findex));
692  }
693  break;
694 
695  case '#': /* ExternalScriptFunctionCall */
696  {
697  WsPragmaUse *use = ws_hash_get(compiler->pragma_use_hash,
698  expr->u.call.base);
699  WsUInt16 findex;
700 
701  if (use == NULL)
702  {
703  ws_src_error(compiler, expr->line,
704  "unknown external compilation unit `%s'",
705  expr->u.call.base);
706  return;
707  }
708 
709  /* Insert the function name to the byte-code pool. */
711  compiler->bc, &findex,
712  (unsigned char *) expr->u.call.name,
713  strlen(expr->u.call.name)))
714  {
715  ws_error_memory(compiler);
716  return;
717  }
718 
719  /* Emit assembler. */
720  ws_asm_link(compiler,
721  ws_asm_call_url(compiler, expr->line,
722  findex, use->urlindex,
723  expr->u.call.arguments->num_items));
724  }
725  break;
726 
727  case '.': /* LibraryFunctionCall */
728  {
729  WsUInt16 lindex;
730  WsUInt8 findex;
731  WsUInt8 num_args;
732  WsBool lindex_found;
733  WsBool findex_found;
734 
735  if (!ws_stdlib_function(expr->u.call.base, expr->u.call.name,
736  &lindex, &findex, &num_args,
737  &lindex_found, &findex_found))
738  {
739  if (!lindex_found)
740  ws_src_error(compiler, expr->line,
741  "unknown system library `%s'",
742  expr->u.call.base);
743  else
744  ws_src_error(compiler, expr->line,
745  "unknown library function `%s.%s'",
746  expr->u.call.base, expr->u.call.name);
747 
748  return;
749  }
750  /* Check the argument count. */
751  if (expr->u.call.arguments->num_items != num_args)
752  {
753  ws_src_error(compiler, expr->line,
754  "invalid amount of arguments for `%s.%s': "
755  "expected %u, got %u",
756  expr->u.call.base, expr->u.call.name,
757  num_args, expr->u.call.arguments->num_items);
758  return;
759  }
760 
761  /* Emit assembler. */
762  ws_asm_link(compiler, ws_asm_call_lib(compiler, expr->line, findex,
763  lindex));
764  }
765  break;
766 
767  default:
768  ws_fatal("ws_expr_linearize(): unknown call expression type %x",
769  expr->u.call.type);
770  break;
771  }
772  break;
773 
774  case WS_EXPR_SYMBOL:
775  {
776  WsNamespace *ns = ws_variable_lookup(compiler, expr->u.symbol);
777 
778  if (ns == NULL) {
779  /* An unknown identifier. */
780  ws_src_error(compiler, expr->line, "unknown variable `%s'",
781  expr->u.symbol);
782  return;
783  }
784 
785  /* Create a load instruction for the variable. */
786  ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,
787  WS_ASM_P_LOAD_VAR, ns->vindex));
788  }
789  break;
790 
792  ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
794  break;
795 
796  case WS_EXPR_CONST_TRUE:
797  ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
799  break;
800 
801  case WS_EXPR_CONST_FALSE:
802  ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,
804  break;
805 
806 
808  if (expr->u.integer.ival == 0)
809  ins = ws_asm_ins(compiler, expr->line, WS_ASM_CONST_0);
810  else if (expr->u.integer.ival == 1 && expr->u.integer.sign == 1)
811  ins = ws_asm_ins(compiler, expr->line, WS_ASM_CONST_1);
812  else {
813  WsUInt16 cindex;
814  WsInt32 ival;
815 
816  if (expr->u.integer.sign >= 0) {
817  if (expr->u.integer.ival > (WsUInt32) WS_INT32_MAX)
818  ws_src_error(compiler, expr->line,
819  "integer literal too large");
820  ival = expr->u.integer.ival;
821  } else {
822  if (expr->u.integer.ival > (WsUInt32) WS_INT32_MAX + 1)
823  ws_src_error(compiler, expr->line, "integer too small");
824  ival = - (WsInt32) expr->u.integer.ival;
825  }
826 
827  if (!ws_bc_add_const_int(compiler->bc, &cindex, ival)) {
828  ws_error_memory(compiler);
829  return;
830  }
831  ins = ws_asm_load_const(compiler, expr->line, cindex);
832  }
833 
834  ws_asm_link(compiler, ins);
835  break;
836 
837  case WS_EXPR_CONST_FLOAT:
838  {
839  WsUInt16 cindex;
840 
841  if (!ws_bc_add_const_float(compiler->bc, &cindex, expr->u.fval)) {
842  ws_error_memory(compiler);
843  return;
844  }
845 
846  ws_asm_link(compiler, ws_asm_load_const(compiler, expr->line, cindex));
847  }
848  break;
849 
851  if (expr->u.string.len == 0)
852  ins = ws_asm_ins(compiler, expr->line, WS_ASM_CONST_ES);
853  else {
854  WsUInt16 cindex;
855 
856  if (!ws_bc_add_const_utf8_string(compiler->bc, &cindex,
857  expr->u.string.data,
858  expr->u.string.len)) {
859  ws_error_memory(compiler);
860  return;
861  }
862  ins = ws_asm_load_const(compiler, expr->line, cindex);
863  }
864 
865  ws_asm_link(compiler, ins);
866  break;
867  }
868 }
void ws_asm_link(WsCompiler *compiler, WsAsmIns *ins)
Definition: wsasm.c:93
void ws_fatal(char *fmt,...)
Definition: wserror.c:91
#define WS_ASM_CONST_TRUE
Definition: wsasm.h:175
WsHashPtr pragma_use_hash
Definition: wsint.h:234
struct WsListItemRec * next
Definition: wsstree.h:79
#define WS_ASM_B_RSSHIFT
Definition: wsasm.h:195
WsUInt8 vindex
Definition: wsstree.h:119
WsAsmIns * ws_asm_call_lib(WsCompiler *compiler, WsUInt32 line, WsUInt8 findex, WsUInt16 lindex)
Definition: wsasm.c:867
WsAsmIns * ws_asm_branch(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst, WsAsmIns *label)
Definition: wsasm.c:842
size_t len
Definition: wsutf8.h:81
unsigned long WsUInt32
Definition: wsint.h:122
#define tDIVA
Definition: wsgram.c:238
#define WS_ASM_ADD_ASG
Definition: wsasm.h:180
#define tRSZSHIFTA
Definition: wsgram.c:245
WsBool ws_stdlib_function(const char *library, const char *function, WsUInt16 *lindex_return, WsUInt8 *findex_return, WsUInt8 *num_args_return, WsBool *lindex_found_return, WsBool *findex_found_return)
Definition: wsstdlib.c:341
WsAsmIns * ws_asm_label(WsCompiler *compiler, WsUInt32 line)
Definition: wsasm.c:831
void ws_expr_linearize(WsCompiler *compiler, WsExpression *expr)
Definition: wsstree.c:395
unsigned char * data
Definition: wsutf8.h:84
WsAsmIns * ws_asm_call_url(WsCompiler *compiler, WsUInt32 line, WsUInt16 findex, WsUInt16 urlindex, WsUInt8 args)
Definition: wsasm.c:881
#define WS_INT32_MAX
Definition: wsint.h:109
struct WsExpressionRec::@118::@123 binary
#define WS_ASM_CONST_INVALID
Definition: wsasm.h:174
WsUInt16 urlindex
Definition: wsstree.h:153
#define tRSSHIFTA
Definition: wsgram.c:244
#define WS_ASM_DIV
Definition: wsasm.h:186
#define tREMA
Definition: wsgram.c:242
WsList * params
Definition: wsstree.h:201
#define WS_ASM_CONST_FALSE
Definition: wsasm.h:176
struct WsExpressionRec::@118::@124 unary
#define tLSHIFTA
Definition: wsgram.c:243
#define WS_ASM_P_JUMP
Definition: wsasm.h:226
WsAsmIns * ws_asm_load_const(WsCompiler *compiler, WsUInt32 line, WsUInt16 cindex)
Definition: wsasm.c:908
unsigned char WsUInt8
Definition: wsint.h:116
#define WS_ASM_B_LSHIFT
Definition: wsasm.h:194
#define tIDIVA
Definition: wsgram.c:175
#define WS_ASM_P_TJUMP
Definition: wsasm.h:227
WsAsmIns * ws_asm_call(WsCompiler *compiler, WsUInt32 line, WsUInt8 findex)
Definition: wsasm.c:856
struct WsExpressionRec::@118::@126 postfix_var
#define WS_ASM_REM
Definition: wsasm.h:188
void * data
Definition: wsstree.h:80
WsBc * bc
Definition: wsint.h:218
WsFloat fval
Definition: wsstree.h:384
unsigned short WsUInt16
Definition: wsint.h:119
struct WsExpressionRec::@118::@125 unary_var
WsNamespace * ws_variable_lookup(WsCompilerPtr compiler, char *name)
Definition: wsstree.c:199
WsUInt32 line
Definition: wsstree.h:275
#define tMULA
Definition: wsgram.c:237
#define tSUBA
Definition: wsgram.c:236
struct WsExpressionRec::@118::@122 logical
#define WS_ASM_P_LOAD_VAR
Definition: wsasm.h:231
WsBool ws_bc_add_const_float(WsBc *bc, WsUInt16 *index_return, WsFloat value)
Definition: wsbc.c:881
WsAsmIns * ws_asm_variable(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst, WsUInt8 vindex)
Definition: wsasm.c:896
struct WsExpressionRec::@118::@121 conditional
WsBool defined
Definition: wsstree.h:217
WsAsmIns * ws_asm_ins(WsCompiler *compiler, WsUInt32 line, WsUInt8 opcode)
Definition: wsasm.c:920
WsUtf8String string
Definition: wsstree.h:385
#define WS_ASM_TOBOOL
Definition: wsasm.h:208
#define WS_ASM_B_OR
Definition: wsasm.h:191
WsBool ws_bc_add_const_int(WsBc *bc, WsUInt16 *index_return, WsInt32 value)
Definition: wsbc.c:850
#define WS_ASM_POP
Definition: wsasm.h:210
#define WS_ASM_B_XOR
Definition: wsasm.h:192
WsFunctionHash * ws_function_hash(WsCompilerPtr compiler, char *name)
Definition: wsstree.c:318
WsBool
Definition: wsint.h:128
#define WS_ASM_CONST_1
Definition: wsasm.h:171
WsFunction * functions
Definition: wsint.h:238
WsBool ws_bc_add_const_utf8_string(WsBc *bc, WsUInt16 *index_return, const unsigned char *data, size_t len)
Definition: wsbc.c:912
#define WS_ASM_DECR_VAR
Definition: wsasm.h:164
#define tXORA
Definition: wsgram.c:241
#define WS_ASM_P_STORE_VAR
Definition: wsasm.h:232
#define tORA
Definition: wsgram.c:240
char * symbol
Definition: wsstree.h:379
#define WS_ASM_B_RSZSHIFT
Definition: wsasm.h:196
signed long WsInt32
Definition: wsint.h:121
union WsExpressionRec::@118 u
#define WS_ASM_SUB_ASG
Definition: wsasm.h:181
struct WsExpressionRec::@118::@120 assign
struct WsExpressionRec::@118::@127 call
#define WS_ASM_P_INCR_VAR
Definition: wsasm.h:233
struct WsExpressionRec::@118::@128 integer
#define tADDA
Definition: wsgram.c:235
#define WS_ASM_B_AND
Definition: wsasm.h:190
#define WS_ASM_IDIV
Definition: wsasm.h:187
struct WsExpressionRec::@118::@119 comma
#define tANDA
Definition: wsgram.c:239
#define WS_ASM_CONST_0
Definition: wsasm.h:170
#define WS_ASM_MUL
Definition: wsasm.h:185
void ws_src_error(WsCompilerPtr compiler, WsUInt32 line, char *message,...)
Definition: wserror.c:145
#define WS_ASM_ADD
Definition: wsasm.h:183
void * ws_hash_get(WsHashPtr hash, const char *name)
Definition: wshash.c:167
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
#define WS_ASM_CONST_ES
Definition: wsasm.h:173
WsUInt8 findex
Definition: wsstree.h:220
WsExpressionType type
Definition: wsstree.h:274
#define WS_ASM_SUB
Definition: wsasm.h:184
WsUInt32 num_items
Definition: wsstree.h:90
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::logical, type, WsExpressionRec::u, and WS_EXPR_LOGICAL.

Referenced by yyparse().

943 {
944  WsExpression *expr = expr_alloc(compiler, WS_EXPR_LOGICAL, line);
945 
946  if (expr) {
947  expr->u.logical.type = type;
948  expr->u.logical.left = left;
949  expr->u.logical.right = right;
950  }
951 
952  return expr;
953 }
int type
Definition: smsc_cimd2.c:215
struct WsExpressionRec::@118::@122 logical
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
WsExpression* ws_expr_postfix_var ( WsCompilerPtr  compiler,
WsUInt32  line,
WsBool  addp,
char *  variable 
)

Definition at line 1010 of file wsstree.c.

References expr_alloc(), WsCompilerRec::pool_stree, WsExpressionRec::postfix_var, WsExpressionRec::u, ws_error_memory(), WS_EXPR_POSTFIX_VAR, ws_f_strdup(), and ws_lexer_free_block().

Referenced by yyparse().

1012 {
1013  WsExpression *expr = expr_alloc(compiler, WS_EXPR_POSTFIX_VAR, line);
1014 
1015  if (expr) {
1016  expr->u.postfix_var.addp = addp;
1017  expr->u.postfix_var.variable = ws_f_strdup(compiler->pool_stree,
1018  variable);
1019  if (expr->u.postfix_var.variable == NULL)
1020  ws_error_memory(compiler);
1021  }
1022  ws_lexer_free_block(compiler, variable);
1023 
1024  return expr;
1025 }
void ws_lexer_free_block(WsCompiler *compiler, void *ptr)
Definition: ws.c:281
struct WsExpressionRec::@118::@126 postfix_var
void * ws_f_strdup(WsFastMalloc *pool, const char *str)
Definition: wsfalloc.c:177
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
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(), and ws_lexer_free_block().

Referenced by yyparse().

1053 {
1054  WsExpression *expr = expr_alloc(compiler, WS_EXPR_SYMBOL, line);
1055 
1056  if (expr) {
1057  expr->u.symbol = ws_f_strdup(compiler->pool_stree, identifier);
1058  if (expr->u.symbol == NULL)
1059  ws_error_memory(compiler);
1060  }
1061 
1062  ws_lexer_free_block(compiler, identifier);
1063 
1064  return expr;
1065 }
void ws_lexer_free_block(WsCompiler *compiler, void *ptr)
Definition: ws.c:281
void * ws_f_strdup(WsFastMalloc *pool, const char *str)
Definition: wsfalloc.c:177
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
char * symbol
Definition: wsstree.h:379
union WsExpressionRec::@118 u
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsExpression* ws_expr_unary ( WsCompilerPtr  compiler,
WsUInt32  line,
int  type,
WsExpression expression 
)

Definition at line 971 of file wsstree.c.

References expr_alloc(), WsExpressionRec::integer, type, WsExpressionRec::type, WsExpressionRec::u, WsExpressionRec::unary, WS_ASM_UMINUS, WS_EXPR_CONST_INTEGER, and WS_EXPR_UNARY.

Referenced by yyparse().

973 {
974  WsExpression *expr;
975 
976  /* Handle negative integers here as a special case of constant folding,
977  * in order to get -2147483648 right. */
978  if (type == WS_ASM_UMINUS && expression->type == WS_EXPR_CONST_INTEGER) {
979  expression->u.integer.sign = - expression->u.integer.sign;
980  return expression;
981  }
982 
983  expr = expr_alloc(compiler, WS_EXPR_UNARY, line);
984  if (expr) {
985  expr->u.unary.type = type;
986  expr->u.unary.expr = expression;
987  }
988 
989  return expr;
990 }
int type
Definition: smsc_cimd2.c:215
struct WsExpressionRec::@118::@124 unary
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
#define WS_ASM_UMINUS
Definition: wsasm.h:182
struct WsExpressionRec::@118::@128 integer
WsExpressionType type
Definition: wsstree.h:274
WsExpression* ws_expr_unary_var ( WsCompilerPtr  compiler,
WsUInt32  line,
WsBool  addp,
char *  variable 
)

Definition at line 993 of file wsstree.c.

References expr_alloc(), WsCompilerRec::pool_stree, WsExpressionRec::u, WsExpressionRec::unary_var, ws_error_memory(), WS_EXPR_UNARY_VAR, ws_f_strdup(), and ws_lexer_free_block().

Referenced by yyparse().

995 {
996  WsExpression *expr = expr_alloc(compiler, WS_EXPR_UNARY_VAR, line);
997 
998  if (expr) {
999  expr->u.unary_var.addp = addp;
1000  expr->u.unary_var.variable = ws_f_strdup(compiler->pool_stree, variable);
1001  if (expr->u.unary_var.variable == NULL)
1002  ws_error_memory(compiler);
1003  }
1004  ws_lexer_free_block(compiler, variable);
1005 
1006  return expr;
1007 }
void ws_lexer_free_block(WsCompiler *compiler, void *ptr)
Definition: ws.c:281
struct WsExpressionRec::@118::@125 unary_var
void * ws_f_strdup(WsFastMalloc *pool, const char *str)
Definition: wsfalloc.c:177
static WsExpression * expr_alloc(WsCompiler *compiler, WsExpressionType type, WsUInt32 line)
Definition: wsstree.c:873
union WsExpressionRec::@118 u
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsFormalParm* ws_formal_parameter ( WsCompilerPtr  compiler,
WsUInt32  line,
char *  name 
)

Definition at line 93 of file wsstree.c.

References WsFormalParmRec::line, name, WsFormalParmRec::name, WsCompilerRec::pool_stree, ws_error_memory(), and ws_f_malloc().

Referenced by yyparse().

95 {
96  WsFormalParm *parm = ws_f_malloc(compiler->pool_stree, sizeof(*parm));
97 
98  if (parm == NULL)
99  ws_error_memory(compiler);
100  else {
101  parm->line = line;
102  parm->name = name;
103  }
104 
105  return parm;
106 }
char * name
Definition: wsstree.h:493
WsUInt32 line
Definition: wsstree.h:492
char * name
Definition: smsc_cimd2.c:212
Definition: seewbmp.c:154
WsFastMalloc * pool_stree
Definition: wsint.h:204
void * ws_f_malloc(WsFastMalloc *pool, size_t size)
Definition: wsfalloc.c:102
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
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, WsFunctionRec::findex, WsFunctionHashRec::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(), and WS_TRUE.

Referenced by yyparse().

345 {
346  WsFunctionHash *hash;
347  WsFunction *f = ws_realloc(compiler->functions,
348  ((compiler->num_functions + 1)
349  * sizeof(WsFunction)));
350 
351  if (f == NULL) {
352  ws_free(name);
353  ws_error_memory(compiler);
354  return;
355  }
356 
357  if (externp)
358  compiler->num_extern_functions++;
359  else
360  compiler->num_local_functions++;
361 
362  compiler->functions = f;
363  f = &compiler->functions[compiler->num_functions];
364 
365  f->findex = compiler->num_functions++;
366 
367  f->externp = externp;
368  f->name = name;
369  f->line = line;
370  f->params = params;
371  f->block = block;
372 
373  /* Update the function name hash. */
374 
375  hash = ws_function_hash(compiler, name);
376  if (hash == NULL) {
377  ws_error_memory(compiler);
378  return;
379  }
380 
381  if (hash->defined) {
382  ws_src_error(compiler, line, "redefinition of `%s'", name);
383  ws_src_error(compiler,
384  compiler->functions[hash->findex].line,
385  "`%s' previously defined here", name);
386  return;
387  }
388 
389  hash->defined = WS_TRUE;
390  hash->findex = f->findex;
391 }
WsList * block
Definition: wsstree.h:202
Definition: wsint.h:131
WsUInt32 line
Definition: wsstree.h:200
void ws_free(void *ptr)
Definition: wsalloc.c:139
WsUInt32 num_local_functions
Definition: wsint.h:257
void * ws_realloc(void *ptr, size_t size)
Definition: wsalloc.c:89
WsUInt32 num_functions
Definition: wsint.h:237
WsList * params
Definition: wsstree.h:201
WsBool externp
Definition: wsstree.h:198
char * name
Definition: smsc_cimd2.c:212
WsBool defined
Definition: wsstree.h:217
WsFunctionHash * ws_function_hash(WsCompilerPtr compiler, char *name)
Definition: wsstree.c:318
WsFunction * functions
Definition: wsint.h:238
WsUInt8 findex
Definition: wsstree.h:197
WsUInt32 num_extern_functions
Definition: wsint.h:256
void ws_src_error(WsCompilerPtr compiler, WsUInt32 line, char *message,...)
Definition: wserror.c:145
char * name
Definition: wsstree.h:199
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsUInt8 findex
Definition: wsstree.h:220
WsFunctionHash* ws_function_hash ( WsCompilerPtr  compiler,
char *  name 
)

Definition at line 318 of file wsstree.c.

References WsCompilerRec::functions_hash, ws_calloc(), ws_error_memory(), ws_free(), ws_hash_get(), and ws_hash_put().

Referenced by compile_stream(), ws_expr_linearize(), ws_function(), and yyparse().

319 {
321 
322  if (i)
323  return i;
324 
325  /* Must create a new mapping. */
326 
327  i = ws_calloc(1, sizeof(*i));
328  if (i == NULL) {
329  ws_error_memory(compiler);
330  return NULL;
331  }
332 
333  if (!ws_hash_put(compiler->functions_hash, name, i)) {
334  ws_free(i);
335  ws_error_memory(compiler);
336  return NULL;
337  }
338 
339  return i;
340 }
void * ws_calloc(size_t num, size_t size)
Definition: wsalloc.c:83
WsHashPtr functions_hash
Definition: wsint.h:242
void ws_free(void *ptr)
Definition: wsalloc.c:139
char * name
Definition: smsc_cimd2.c:212
WsBool ws_hash_put(WsHashPtr hash, const char *name, void *data)
Definition: wshash.c:126
void * ws_hash_get(WsHashPtr hash, const char *name)
Definition: wshash.c:167
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsHashPtr ws_function_hash_create ( void  )

Definition at line 312 of file wsstree.c.

References function_hash_destructor(), and ws_hash_create().

Referenced by compile_stream().

313 {
315 }
static void function_hash_destructor(void *item, void *context)
Definition: wsstree.c:306
WsHashPtr ws_hash_create(WsHashItemDestructor destructor, void *context)
Definition: wshash.c:103
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(), and ws_f_calloc().

Referenced by yyparse().

122 {
123  WsListItem *item;
124 
125  if (list == NULL)
126  /* A recovery code for previous memory allocation problems. */
127  return;
128 
129  item = ws_f_calloc(compiler->pool_stree, 1, sizeof(*item));
130  if (item == NULL) {
131  ws_error_memory(compiler);
132  return;
133  }
134 
135  item->data = value;
136 
137  if (list->tail) {
138  list->tail->next = item;
139  list->tail = item;
140  } else
141  list->head = list->tail = item;
142 
143  list->num_items++;
144 }
struct WsListItemRec * next
Definition: wsstree.h:79
WsListItem * head
Definition: wsstree.h:88
void * data
Definition: wsstree.h:80
WsListItem * tail
Definition: wsstree.h:89
void * ws_f_calloc(WsFastMalloc *pool, size_t num, size_t size)
Definition: wsfalloc.c:150
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsUInt32 num_items
Definition: wsstree.h:90
WsList* ws_list_new ( WsCompiler compiler)

Definition at line 110 of file wsstree.c.

References WsCompilerRec::pool_stree, ws_error_memory(), and ws_f_calloc().

Referenced by yyparse().

111 {
112  WsList *list = ws_f_calloc(compiler->pool_stree, 1, sizeof(*list));
113 
114  if (list == NULL)
115  ws_error_memory(compiler);
116 
117  return list;
118 }
void * ws_f_calloc(WsFastMalloc *pool, size_t num, size_t size)
Definition: wsfalloc.c:150
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsPragmaMetaBody* ws_pragma_meta_body ( WsCompilerPtr  compiler,
WsUtf8String property_name,
WsUtf8String content,
WsUtf8String scheme 
)

Definition at line 271 of file wsstree.c.

References content, WsPragmaMetaBodyRec::content, WsPragmaMetaBodyRec::property_name, WsPragmaMetaBodyRec::scheme, ws_calloc(), and ws_error_memory().

Referenced by yyparse().

275 {
276  WsPragmaMetaBody *mb = ws_calloc(1, sizeof(*mb));
277 
278  if (mb == NULL) {
279  ws_error_memory(compiler);
280  return NULL;
281  }
282 
283  mb->property_name = property_name;
284  mb->content = content;
285  mb->scheme = scheme;
286 
287  return mb;
288 }
void * ws_calloc(size_t num, size_t size)
Definition: wsalloc.c:83
WsUtf8String * scheme
Definition: wsstree.h:178
WsUtf8String * property_name
Definition: wsstree.h:176
WsUtf8String * content
Definition: wsstree.h:177
static Octstr * content
Definition: mtbatch.c:87
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
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(), and ws_lexer_free_utf8().

Referenced by yyparse().

292 {
293  if (mb == NULL)
294  return;
295 
296  ws_lexer_free_utf8(compiler, mb->property_name);
297  ws_lexer_free_utf8(compiler, mb->content);
298  ws_lexer_free_utf8(compiler, mb->scheme);
299 
300  ws_free(mb);
301 }
void ws_free(void *ptr)
Definition: wsalloc.c:139
WsUtf8String * scheme
Definition: wsstree.h:178
WsUtf8String * property_name
Definition: wsstree.h:176
WsUtf8String * content
Definition: wsstree.h:177
void ws_lexer_free_utf8(WsCompiler *compiler, WsUtf8String *string)
Definition: ws.c:305
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, WsPragmaUseRec::urlindex, 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(), and ws_src_error().

Referenced by yyparse().

222 {
223  WsPragmaUse *u = ws_calloc(1, sizeof(*u));
224  WsPragmaUse *uold;
225 
226  /* Do we already know this pragma? */
227  uold = ws_hash_get(compiler->pragma_use_hash, identifier);
228  if (uold) {
229  ws_src_error(compiler, line, "redefinition of pragma `%s'", identifier);
230  ws_src_error(compiler, uold->line, "`%s' previously defined here",
231  identifier);
232  goto error_cleanup;
233  }
234 
235  if (u == NULL)
236  goto error;
237 
238  u->line = line;
239 
240  /* Insert the URL to the byte-code module. */
241  if (!ws_bc_add_const_utf8_string(compiler->bc, &u->urlindex, url->data,
242  url->len))
243  goto error;
244 
245  /* Add it to the use pragma hash. */
246  if (!ws_hash_put(compiler->pragma_use_hash, identifier, u))
247  goto error;
248 
249  /* Cleanup. */
250 
251  ws_lexer_free_block(compiler, identifier);
252  ws_lexer_free_utf8(compiler, url);
253 
254  return;
255 
256  /* Error handling. */
257 
258 error:
259 
260  ws_error_memory(compiler);
261 
262 error_cleanup:
263 
264  ws_free(u);
265  ws_lexer_free_block(compiler, identifier);
266  ws_lexer_free_utf8(compiler, url);
267 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void * ws_calloc(size_t num, size_t size)
Definition: wsalloc.c:83
WsHashPtr pragma_use_hash
Definition: wsint.h:234
size_t len
Definition: wsutf8.h:81
void ws_free(void *ptr)
Definition: wsalloc.c:139
unsigned char * data
Definition: wsutf8.h:84
WsUInt16 urlindex
Definition: wsstree.h:153
WsUInt32 line
Definition: wsstree.h:149
void ws_lexer_free_block(WsCompiler *compiler, void *ptr)
Definition: ws.c:281
WsBc * bc
Definition: wsint.h:218
WsBool ws_bc_add_const_utf8_string(WsBc *bc, WsUInt16 *index_return, const unsigned char *data, size_t len)
Definition: wsbc.c:912
void ws_lexer_free_utf8(WsCompiler *compiler, WsUtf8String *string)
Definition: ws.c:305
void ws_src_error(WsCompilerPtr compiler, WsUInt32 line, char *message,...)
Definition: wserror.c:145
WsBool ws_hash_put(WsHashPtr hash, const char *name, void *data)
Definition: wshash.c:126
void * ws_hash_get(WsHashPtr hash, const char *name)
Definition: wshash.c:167
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsHashPtr ws_pragma_use_hash_create ( void  )

Definition at line 214 of file wsstree.c.

References pragma_use_hash_destructor(), and ws_hash_create().

Referenced by compile_stream().

215 {
217 }
static void pragma_use_hash_destructor(void *item, void *context)
Definition: wsstree.c:208
WsHashPtr ws_hash_create(WsHashItemDestructor destructor, void *context)
Definition: wshash.c:103
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, and WS_STMT_BLOCK.

Referenced by yyparse().

1391 {
1392  WsStatement *stmt = stmt_alloc(compiler, WS_STMT_BLOCK, fline, lline);
1393 
1394  if (stmt)
1395  stmt->u.block = block;
1396 
1397  return stmt;
1398 }
WsList * block
Definition: wsstree.h:529
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
union WsStatementRec::@129 u
WsStatement* ws_stmt_break ( WsCompiler compiler,
WsUInt32  line 
)

Definition at line 1485 of file wsstree.c.

References stmt_alloc(), and WS_STMT_BREAK.

Referenced by yyparse().

1486 {
1487  return stmt_alloc(compiler, WS_STMT_BREAK, line, line);
1488 }
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
WsStatement* ws_stmt_continue ( WsCompiler compiler,
WsUInt32  line 
)

Definition at line 1479 of file wsstree.c.

References stmt_alloc(), and WS_STMT_CONTINUE.

Referenced by yyparse().

1480 {
1481  return stmt_alloc(compiler, WS_STMT_CONTINUE, line, line);
1482 }
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
WsStatement* ws_stmt_empty ( WsCompiler compiler,
WsUInt32  line 
)

Definition at line 1413 of file wsstree.c.

References stmt_alloc(), and WS_STMT_EMPTY.

Referenced by yyparse().

1414 {
1415  return stmt_alloc(compiler, WS_STMT_EMPTY, line, line);
1416 }
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
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, and WS_STMT_EXPR.

Referenced by yyparse().

1421 {
1422  WsStatement *stmt = stmt_alloc(compiler, WS_STMT_EXPR, line, line);
1423 
1424  if (stmt)
1425  stmt->u.expr = expr;
1426 
1427  return stmt;
1428 }
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
WsExpression * expr
Definition: wsstree.h:531
union WsStatementRec::@129 u
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 init, WsStatementRec::s_for, stmt_alloc(), WsStatementRec::u, and WS_STMT_FOR.

Referenced by yyparse().

1450 {
1451  WsStatement *stmt = stmt_alloc(compiler, WS_STMT_FOR, line, line);
1452 
1453  if (stmt) {
1454  stmt->u.s_for.init = init;
1455  stmt->u.s_for.e1 = e1;
1456  stmt->u.s_for.e2 = e2;
1457  stmt->u.s_for.e3 = e3;
1458  stmt->u.s_for.stmt = stmt_body;
1459  }
1460 
1461  return stmt;
1462 }
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
static int init
Definition: gwlib.c:69
union WsStatementRec::@129 u
struct WsStatementRec::@129::@131 s_for
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::s_if, stmt_alloc(), WsStatementRec::u, and WS_STMT_IF.

Referenced by yyparse().

1434 {
1435  WsStatement *stmt = stmt_alloc(compiler, WS_STMT_IF, line, line);
1436 
1437  if (stmt) {
1438  stmt->u.s_if.expr = expr;
1439  stmt->u.s_if.s_then = s_then;
1440  stmt->u.s_if.s_else = s_else;
1441  }
1442 
1443  return stmt;
1444 }
struct WsStatementRec::@129::@130 s_if
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
union WsStatementRec::@129 u
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::expr, WsStatementRec::first_line, WsListRec::head, WsContBreakRec::l_break, WsContBreakRec::l_cont, WsStatementRec::last_line, linearize_variable_init(), WsListItemRec::next, WsContBreakRec::next, WsCompilerRec::pool_stree, WsStatementRec::s_for, WsStatementRec::s_if, WsStatementRec::s_while, 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_RETURN, WS_STMT_VARIABLE, and WS_STMT_WHILE.

Referenced by compile_stream().

1158 {
1159  WsListItem *li;
1160  WsAsmIns *ins;
1161 
1162  switch (stmt->type) {
1163  case WS_STMT_BLOCK:
1164  for (li = stmt->u.block->head; li; li = li->next)
1165  ws_stmt_linearize(compiler, li->data);
1166  break;
1167 
1168  case WS_STMT_VARIABLE:
1169  linearize_variable_init(compiler, stmt->u.var, stmt->first_line);
1170  break;
1171 
1172  case WS_STMT_EMPTY:
1173  /* Nothing here. */
1174  break;
1175 
1176  case WS_STMT_EXPR:
1177  ws_expr_linearize(compiler, stmt->u.expr);
1178 
1179  /* Pop the expressions result from the stack. Otherwise loops
1180  could eventually cause stack overflows. */
1181  ws_asm_link(compiler, ws_asm_ins(compiler, stmt->last_line, WS_ASM_POP));
1182  break;
1183 
1184  case WS_STMT_IF:
1185  {
1186  WsAsmIns *l_else = ws_asm_label(compiler,
1187  (stmt->u.s_if.s_else
1188  ? stmt->u.s_if.s_else->first_line
1189  : stmt->last_line));
1190  WsAsmIns *l_end = ws_asm_label(compiler, stmt->last_line);
1191 
1192  /* Linearize the expression. */
1193  ws_expr_linearize(compiler, stmt->u.s_if.expr);
1194 
1195  /* If the result is false, jump to the else-branch. */
1196  ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
1197  WS_ASM_P_TJUMP, l_else));
1198 
1199  /* Else, execute the then-branch and jump to the end. */
1200  ws_stmt_linearize(compiler, stmt->u.s_if.s_then);
1201  ws_asm_link(compiler, ws_asm_branch(compiler, stmt->last_line,
1202  WS_ASM_P_JUMP, l_end));
1203 
1204  /* Then else-branch. */
1205  ws_asm_link(compiler, l_else);
1206 
1207  /* Linearize the else-branch if it is present. */
1208  if (stmt->u.s_if.s_else)
1209  ws_stmt_linearize(compiler, stmt->u.s_if.s_else);
1210 
1211  /* Insert the end label. */
1212  ws_asm_link(compiler, l_end);
1213  }
1214  break;
1215 
1216  case WS_STMT_FOR:
1217  {
1218  WsAsmIns *l_loop = ws_asm_label(compiler, stmt->first_line);
1219  WsAsmIns *l_cont = ws_asm_label(compiler, stmt->first_line);
1220  WsAsmIns *l_break = ws_asm_label(compiler, stmt->first_line);
1221  WsContBreak *cb;
1222 
1223  /* Store the labels to the compiler. */
1224 
1225  cb = ws_f_calloc(compiler->pool_stree, 1, sizeof(*cb));
1226  if (cb == NULL) {
1227  ws_error_memory(compiler);
1228  return;
1229  }
1230 
1231  cb->next = compiler->cont_break;
1232  compiler->cont_break = cb;
1233 
1234  cb->l_cont = l_cont;
1235  cb->l_break = l_break;
1236 
1237  /* Linearize the possible init code. */
1238  if (stmt->u.s_for.init)
1239  linearize_variable_init(compiler, stmt->u.s_for.init,
1240  stmt->first_line);
1241  else if (stmt->u.s_for.e1) {
1242  /* Linearize the init. */
1243  ws_expr_linearize(compiler, stmt->u.s_for.e1);
1244 
1245  /* Pop the result. */
1246  ws_asm_link(compiler, ws_asm_ins(compiler, stmt->first_line,
1247  WS_ASM_POP));
1248  }
1249 
1250  /* Insert the loop label. */
1251  ws_asm_link(compiler, l_loop);
1252 
1253  /* Linearize the condition. */
1254  if (stmt->u.s_for.e2) {
1255  ws_expr_linearize(compiler, stmt->u.s_for.e2);
1256 
1257  /* If false, jump out. */
1258  ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
1259  WS_ASM_P_TJUMP, l_break));
1260  }
1261 
1262  /* Linearize the body statement. */
1263  ws_stmt_linearize(compiler, stmt->u.s_for.stmt);
1264 
1265  /* Link the continue label. */
1266  ws_asm_link(compiler, l_cont);
1267 
1268  /* Linearize the update expression. */
1269  if (stmt->u.s_for.e3) {
1270  ws_expr_linearize(compiler, stmt->u.s_for.e3);
1271 
1272  /* Pop the result. */
1273  ws_asm_link(compiler, ws_asm_ins(compiler, stmt->first_line,
1274  WS_ASM_POP));
1275  }
1276 
1277  /* Jump to the loop label to check the condition. */
1278  ws_asm_link(compiler, ws_asm_branch(compiler, stmt->last_line,
1279  WS_ASM_P_JUMP, l_loop));
1280 
1281  /* Insert the break label. */
1282  ws_asm_link(compiler, l_break);
1283 
1284  /* Pop the cont-break block. */
1285  compiler->cont_break = compiler->cont_break->next;
1286  }
1287  break;
1288 
1289  case WS_STMT_WHILE:
1290  {
1291  WsAsmIns *l_cont = ws_asm_label(compiler, stmt->first_line);
1292  WsAsmIns *l_break = ws_asm_label(compiler,
1293  stmt->u.s_while.stmt->last_line);
1294  WsContBreak *cb;
1295 
1296  /* Store the labels to the compiler. */
1297 
1298  cb = ws_f_calloc(compiler->pool_stree, 1, sizeof(*cb));
1299  if (cb == NULL) {
1300  ws_error_memory(compiler);
1301  return;
1302  }
1303 
1304  cb->next = compiler->cont_break;
1305  compiler->cont_break = cb;
1306 
1307  cb->l_cont = l_cont;
1308  cb->l_break = l_break;
1309 
1310  /* Insert the continue label. */
1311  ws_asm_link(compiler, l_cont);
1312 
1313  /* Linearize the expression. */
1314  ws_expr_linearize(compiler, stmt->u.s_while.expr);
1315 
1316  /* If false, jump out. */
1317  ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
1318  WS_ASM_P_TJUMP, l_break));
1319 
1320  /* Linearize the body statement. */
1321  ws_stmt_linearize(compiler, stmt->u.s_while.stmt);
1322 
1323  /* And jump to the continue label to check the expression. */
1324  ws_asm_link(compiler, ws_asm_branch(compiler, stmt->last_line,
1325  WS_ASM_P_JUMP, l_cont));
1326 
1327  /* Insert the break label. */
1328  ws_asm_link(compiler, l_break);
1329 
1330  /* Pop the cont-break block. */
1331  compiler->cont_break = compiler->cont_break->next;
1332  }
1333  break;
1334 
1335  case WS_STMT_CONTINUE:
1336  if (compiler->cont_break == NULL)
1337  ws_src_error(compiler, stmt->first_line,
1338  "continue statement not within a loop");
1339 
1340  ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
1341  WS_ASM_P_JUMP,
1342  compiler->cont_break->l_cont));
1343  break;
1344 
1345  case WS_STMT_BREAK:
1346  if (compiler->cont_break == NULL)
1347  ws_src_error(compiler, stmt->first_line,
1348  "break statement not within a loop");
1349 
1350  ws_asm_link(compiler, ws_asm_branch(compiler, stmt->first_line,
1351  WS_ASM_P_JUMP,
1352  compiler->cont_break->l_break));
1353  break;
1354 
1355  case WS_STMT_RETURN:
1356  if (stmt->u.expr) {
1357  /* Linearize the return value and return it. */
1358  ws_expr_linearize(compiler, stmt->u.expr);
1359  ins = ws_asm_ins(compiler, stmt->first_line, WS_ASM_RETURN);
1360  } else
1361  /* Return an empty string. */
1362  ins = ws_asm_ins(compiler, stmt->first_line, WS_ASM_RETURN_ES);
1363 
1364  ws_asm_link(compiler, ins);
1365  break;
1366  }
1367 }
void ws_asm_link(WsCompiler *compiler, WsAsmIns *ins)
Definition: wsasm.c:93
struct WsListItemRec * next
Definition: wsstree.h:79
WsList * block
Definition: wsstree.h:529
struct WsStatementRec::@129::@130 s_if
WsAsmIns * ws_asm_branch(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst, WsAsmIns *label)
Definition: wsasm.c:842
WsAsmIns * ws_asm_label(WsCompiler *compiler, WsUInt32 line)
Definition: wsasm.c:831
void ws_expr_linearize(WsCompiler *compiler, WsExpression *expr)
Definition: wsstree.c:395
struct WsContBreakRec * next
Definition: wsint.h:178
#define WS_ASM_RETURN
Definition: wsasm.h:215
WsExpression * expr
Definition: wsstree.h:531
WsListItem * head
Definition: wsstree.h:88
WsList * var
Definition: wsstree.h:530
static void linearize_variable_init(WsCompiler *compiler, WsList *list, WsUInt32 line)
Definition: wsstree.c:1133
#define WS_ASM_P_JUMP
Definition: wsasm.h:226
WsUInt32 last_line
Definition: wsstree.h:525
struct WsStatementRec::@129::@132 s_while
WsAsmIns * l_cont
Definition: wsint.h:179
#define WS_ASM_P_TJUMP
Definition: wsasm.h:227
void * data
Definition: wsstree.h:80
WsContBreak * cont_break
Definition: wsint.h:249
WsUInt32 first_line
Definition: wsstree.h:524
WsAsmIns * ws_asm_ins(WsCompiler *compiler, WsUInt32 line, WsUInt8 opcode)
Definition: wsasm.c:920
#define WS_ASM_POP
Definition: wsasm.h:210
WsStatementType type
Definition: wsstree.h:523
void * ws_f_calloc(WsFastMalloc *pool, size_t num, size_t size)
Definition: wsfalloc.c:150
WsAsmIns * l_break
Definition: wsint.h:180
union WsStatementRec::@129 u
WsFastMalloc * pool_stree
Definition: wsint.h:204
void ws_src_error(WsCompilerPtr compiler, WsUInt32 line, char *message,...)
Definition: wserror.c:145
struct WsStatementRec::@129::@131 s_for
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
#define WS_ASM_RETURN_ES
Definition: wsasm.h:216
void ws_stmt_linearize(WsCompiler *compiler, WsStatement *stmt)
Definition: wsstree.c:1157
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, and WS_STMT_RETURN.

Referenced by yyparse().

1493 {
1494  WsStatement *stmt = stmt_alloc(compiler, WS_STMT_RETURN, line, line);
1495 
1496  if (stmt)
1497  stmt->u.expr = expr;
1498 
1499  return stmt;
1500 }
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
WsExpression * expr
Definition: wsstree.h:531
union WsStatementRec::@129 u
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, and WS_STMT_VARIABLE.

Referenced by yyparse().

1403 {
1404  WsStatement *stmt = stmt_alloc(compiler, WS_STMT_VARIABLE, line, line);
1405 
1406  if (stmt)
1407  stmt->u.var = variables;
1408 
1409  return stmt;
1410 }
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
WsList * var
Definition: wsstree.h:530
union WsStatementRec::@129 u
WsStatement* ws_stmt_while ( WsCompiler compiler,
WsUInt32  line,
WsExpression expr,
WsStatement stmt_arg 
)

Definition at line 1465 of file wsstree.c.

References WsStatementRec::s_while, stmt_alloc(), WsStatementRec::u, and WS_STMT_WHILE.

Referenced by yyparse().

1467 {
1468  WsStatement *stmt = stmt_alloc(compiler, WS_STMT_WHILE, line, line);
1469 
1470  if (stmt) {
1471  stmt->u.s_while.expr = expr;
1472  stmt->u.s_while.stmt = stmt_arg;
1473  }
1474 
1475  return stmt;
1476 }
static WsStatement * stmt_alloc(WsCompiler *compiler, WsStatementType type, WsUInt32 first_line, WsUInt32 last_line)
Definition: wsstree.c:1372
struct WsStatementRec::@129::@132 s_while
union WsStatementRec::@129 u
WsVarDec* ws_variable_declaration ( WsCompilerPtr  compiler,
char *  name,
WsExpression expr 
)

Definition at line 78 of file wsstree.c.

References WsVarDecRec::expr, name, WsVarDecRec::name, WsCompilerRec::pool_stree, ws_error_memory(), and ws_f_malloc().

Referenced by yyparse().

80 {
81  WsVarDec *vardec = ws_f_malloc(compiler->pool_stree, sizeof(*vardec));
82 
83  if (vardec == NULL)
84  ws_error_memory(compiler);
85  else {
86  vardec->name = name;
87  vardec->expr = expr;
88  }
89 
90  return vardec;
91 }
char * name
Definition: smsc_cimd2.c:212
WsExpression * expr
Definition: wsstree.h:480
WsFastMalloc * pool_stree
Definition: wsint.h:204
void * ws_f_malloc(WsFastMalloc *pool, size_t size)
Definition: wsfalloc.c:102
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
char * name
Definition: wsstree.h:479
WsNamespace* ws_variable_define ( WsCompilerPtr  compiler,
WsUInt32  line,
WsBool  variablep,
char *  name 
)

Definition at line 160 of file wsstree.c.

References WsNamespaceRec::line, WsCompilerRec::next_vindex, WsCompilerRec::variables_hash, WsNamespaceRec::vindex, ws_calloc(), ws_error_memory(), ws_free(), ws_hash_get(), ws_hash_put(), and ws_src_error().

Referenced by compile_stream(), and linearize_variable_init().

162 {
163  WsNamespace *ns;
164 
165  /* Is the symbol already defined? */
166  ns = ws_hash_get(compiler->variables_hash, name);
167  if (ns) {
168  ws_src_error(compiler, line, "redeclaration of `%s'", name);
169  ws_src_error(compiler, ns->line, "`%s' previously declared here", name);
170  return NULL;
171  }
172 
173  /* Can we still define more variables? */
174  if (compiler->next_vindex > 255) {
175  /* No we can't. */
176  ws_src_error(compiler, line, "too many local variables");
177  return NULL;
178  }
179 
180  ns = ws_calloc(1, sizeof(*ns));
181  if (ns == NULL) {
182  ws_error_memory(compiler);
183  return NULL;
184  }
185 
186  ns->line = line;
187  ns->vindex = compiler->next_vindex++;
188 
189  if (!ws_hash_put(compiler->variables_hash, name, ns)) {
190  ws_free(ns);
191  ws_error_memory(compiler);
192  return NULL;
193  }
194 
195  return ns;
196 }
void * ws_calloc(size_t num, size_t size)
Definition: wsalloc.c:83
WsUInt8 vindex
Definition: wsstree.h:119
WsUInt32 line
Definition: wsstree.h:116
void ws_free(void *ptr)
Definition: wsalloc.c:139
WsUInt32 next_vindex
Definition: wsint.h:245
char * name
Definition: smsc_cimd2.c:212
WsHashPtr variables_hash
Definition: wsint.h:246
void ws_src_error(WsCompilerPtr compiler, WsUInt32 line, char *message,...)
Definition: wserror.c:145
WsBool ws_hash_put(WsHashPtr hash, const char *name, void *data)
Definition: wshash.c:126
void * ws_hash_get(WsHashPtr hash, const char *name)
Definition: wshash.c:167
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsHashPtr ws_variable_hash_create ( void  )

Definition at line 154 of file wsstree.c.

References variable_hash_destructor(), and ws_hash_create().

Referenced by compile_stream().

155 {
157 }
static void variable_hash_destructor(void *item, void *context)
Definition: wsstree.c:148
WsHashPtr ws_hash_create(WsHashItemDestructor destructor, void *context)
Definition: wshash.c:103
WsNamespace* ws_variable_lookup ( WsCompilerPtr  compiler,
char *  name 
)

Definition at line 199 of file wsstree.c.

References WsCompilerRec::variables_hash, and ws_hash_get().

Referenced by ws_expr_linearize().

200 {
201  return ws_hash_get(compiler->variables_hash, name);
202 }
char * name
Definition: smsc_cimd2.c:212
WsHashPtr variables_hash
Definition: wsint.h:246
void * ws_hash_get(WsHashPtr hash, const char *name)
Definition: wshash.c:167
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.