📄 wsstree.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * * wsstree.c * * Author: Markku Rossi <mtr@iki.fi> * * Copyright (c) 1999-2000 WAPIT OY LTD. * All rights reserved. * * Syntax tree creation, manipulation and byte-code assembler * generation. * */#include "wsint.h"#include "wsgram.h"/* TODO: Constant folding. *//********************* Misc syntax tree structures **********************/WsVarDec *ws_variable_declaration(WsCompilerPtr compiler, char *name, WsExpression *expr){ WsVarDec *vardec = ws_f_malloc(compiler->pool_stree, sizeof(*vardec)); if (vardec == NULL) ws_error_memory(compiler); else { vardec->name = name; vardec->expr = expr; } return vardec;}WsFormalParm *ws_formal_parameter(WsCompilerPtr compiler, WsUInt32 line, char *name){ WsFormalParm *parm = ws_f_malloc(compiler->pool_stree, sizeof(*parm)); if (parm == NULL) ws_error_memory(compiler); else { parm->line = line; parm->name = name; } return parm;}/********************* Linked list **************************************/WsList *ws_list_new(WsCompiler *compiler){ WsList *list = ws_f_calloc(compiler->pool_stree, 1, sizeof(*list)); if (list == NULL) ws_error_memory(compiler); return list;}void ws_list_append(WsCompiler *compiler, WsList *list, void *value){ WsListItem *item; if (list == NULL) /* A recovery code for previous memory allocation problems. */ return; item = ws_f_calloc(compiler->pool_stree, 1, sizeof(*item)); if (item == NULL) { ws_error_memory(compiler); return; } item->data = value; if (list->tail) { list->tail->next = item; list->tail = item; } else list->head = list->tail = item; list->num_items++;}/********************* Namespace for arguments and locals ***************/static void variable_hash_destructor(void *item, void *context){ ws_free(item);}WsHashPtr ws_variable_hash_create(void){ return ws_hash_create(variable_hash_destructor, NULL);}WsNamespace *ws_variable_define(WsCompilerPtr compiler, WsUInt32 line, WsBool variablep, char *name){ WsNamespace *ns; /* Is the symbol already defined? */ ns = ws_hash_get(compiler->variables_hash, name); if (ns) { ws_src_error(compiler, line, "redeclaration of `%s'", name); ws_src_error(compiler, ns->line, "`%s' previously declared here", name); return NULL; } /* Can we still define more variables? */ if (compiler->next_vindex > 255) { /* No we can't. */ ws_src_error(compiler, line, "too many local variables"); return NULL; } ns = ws_calloc(1, sizeof(*ns)); if (ns == NULL) { ws_error_memory(compiler); return NULL; } ns->line = line; ns->vindex = compiler->next_vindex++; if (!ws_hash_put(compiler->variables_hash, name, ns)) { ws_free(ns); ws_error_memory(compiler); return NULL; } return ns;}WsNamespace *ws_variable_lookup(WsCompilerPtr compiler, char *name){ return ws_hash_get(compiler->variables_hash, name);}/********************* Top-level declarations ***************************//* External compilation units. */static void pragma_use_hash_destructor(void *item, void *context){ ws_free(item);}WsHashPtr ws_pragma_use_hash_create(void){ return ws_hash_create(pragma_use_hash_destructor, NULL);}void ws_pragma_use(WsCompilerPtr compiler, WsUInt32 line, char *identifier, WsUtf8String *url){ WsPragmaUse *u = ws_calloc(1, sizeof(*u)); WsPragmaUse *uold; /* Do we already know this pragma? */ uold = ws_hash_get(compiler->pragma_use_hash, identifier); if (uold) { ws_src_error(compiler, line, "redefinition of pragma `%s'", identifier); ws_src_error(compiler, uold->line, "`%s' previously defined here", identifier); goto error_cleanup; } if (u == NULL) goto error; u->line = line; /* Insert the URL to the byte-code module. */ if (!ws_bc_add_const_utf8_string(compiler->bc, &u->urlindex, url->data, url->len)) goto error; /* Add it to the use pragma hash. */ if (!ws_hash_put(compiler->pragma_use_hash, identifier, u)) goto error; /* Cleanup. */ ws_lexer_free_block(compiler, identifier); ws_lexer_free_utf8(compiler, url); return; /* Error handling. */error: ws_error_memory(compiler);error_cleanup: ws_free(u); ws_lexer_free_block(compiler, identifier); ws_lexer_free_utf8(compiler, url);}/* MetaBody of the `use meta' pragmas. */WsPragmaMetaBody *ws_pragma_meta_body(WsCompilerPtr compiler, WsUtf8String *property_name, WsUtf8String *content, WsUtf8String *scheme){ WsPragmaMetaBody *mb = ws_calloc(1, sizeof(*mb)); if (mb == NULL) { ws_error_memory(compiler); return NULL; } mb->property_name = property_name; mb->content = content; mb->scheme = scheme; return mb;}void ws_pragma_meta_body_free(WsCompilerPtr compiler, WsPragmaMetaBody *mb){ if (mb == NULL) return; ws_lexer_free_utf8(compiler, mb->property_name); ws_lexer_free_utf8(compiler, mb->content); ws_lexer_free_utf8(compiler, mb->scheme); ws_free(mb);}/* Functions. */static void function_hash_destructor(void *item, void *context){ ws_free(item);}WsHashPtr ws_function_hash_create(void){ return ws_hash_create(function_hash_destructor, NULL);}WsFunctionHash *ws_function_hash(WsCompilerPtr compiler, char *name){ WsFunctionHash *i = ws_hash_get(compiler->functions_hash, name); if (i) return i; /* Must create a new mapping. */ i = ws_calloc(1, sizeof(*i)); if (i == NULL) { ws_error_memory(compiler); return NULL; } if (!ws_hash_put(compiler->functions_hash, name, i)) { ws_free(i); ws_error_memory(compiler); return NULL; } return i;}void ws_function(WsCompiler *compiler, WsBool externp, char *name, WsUInt32 line, WsList *params, WsList *block){ WsFunctionHash *hash; WsFunction *f = ws_realloc(compiler->functions, ((compiler->num_functions + 1) * sizeof(WsFunction))); if (f == NULL) { ws_free(name); ws_error_memory(compiler); return; } if (externp) compiler->num_extern_functions++; else compiler->num_local_functions++; compiler->functions = f; f = &compiler->functions[compiler->num_functions]; f->findex = compiler->num_functions++; f->externp = externp; f->name = name; f->line = line; f->params = params; f->block = block; /* Update the function name hash. */ hash = ws_function_hash(compiler, name); if (hash == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -