#include "slang_assemble_constructor.h"\r
#include "slang_assemble_typeinfo.h"\r
#include "slang_assemble_conditional.h"\r
+#include "slang_assemble_assignment.h"\r
\r
/* slang_assembly */\r
\r
\r
/* utility functions */\r
\r
-static int sizeof_variable (slang_type_specifier *spec, slang_operation *array_size,\r
- slang_assembly_name_space *space, unsigned int *size)\r
+static int sizeof_variable (slang_type_specifier *spec, slang_type_qualifier qual,\r
+ slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size)\r
{\r
slang_storage_aggregate agg;\r
\r
return 0;\r
}\r
*size += _slang_sizeof_aggregate (&agg);\r
+ if (qual == slang_qual_out || qual == slang_qual_inout)\r
+ *size += 4;\r
slang_storage_aggregate_destruct (&agg);\r
return 1;\r
}\r
unsigned int *size)\r
{\r
var->address = *size;\r
- return sizeof_variable (&var->type.specifier, var->array_size, space, size);\r
+ if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)\r
+ var->address += 4;\r
+ return sizeof_variable (&var->type.specifier, var->type.qualifier, var->array_size, space,\r
+ size);\r
}\r
\r
static int sizeof_variables (slang_variable_scope *vars, unsigned int start, unsigned int stop,\r
slang_assembly_typeinfo_destruct (&ti);\r
/* "out" and "inout" formal parameter requires the actual parameter to be l-value */\r
if (!ti.can_be_referenced &&\r
- f->parameters->variables[j].type.qualifier != slang_qual_out &&\r
- f->parameters->variables[j].type.qualifier != slang_qual_inout)\r
+ (f->parameters->variables[j].type.qualifier == slang_qual_out ||\r
+ f->parameters->variables[j].type.qualifier == slang_qual_inout))\r
break;\r
}\r
if (j == num_params)\r
/* calculate return value and parameters size */\r
param_size = 0;\r
if (fun->header.type.specifier.type != slang_spec_void)\r
- if (!sizeof_variable (&fun->header.type.specifier, NULL, space, ¶m_size))\r
+ if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,\r
+ ¶m_size))\r
return 0;\r
info.ret_size = param_size;\r
if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, ¶m_size))\r
else\r
{\r
size = 0;\r
- if (!sizeof_variable (&ti.spec, NULL, space, &size))\r
+ if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size))\r
{\r
slang_assembly_typeinfo_destruct (&ti);\r
return 0;\r
return 1;\r
}\r
/* XXX: general swizzle! */\r
-static int dereference (slang_assembly_file *file, slang_operation *op,\r
+int dereference (slang_assembly_file *file, slang_operation *op,\r
slang_assembly_name_space *space, slang_assembly_local_info *info)\r
{\r
slang_assembly_typeinfo ti;\r
unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
slang_assembly_local_info *info)\r
{\r
- unsigned int ret_size, i;\r
+ unsigned int i;\r
slang_assembly_stack_info stk;\r
\r
/* make room for the return value, if any */\r
- ret_size = 0;\r
- if (!sizeof_variable (&fun->header.type.specifier, NULL, space, &ret_size))\r
- return 0;\r
- if (ret_size > 0)\r
+ if (fun->header.type.specifier.type != slang_spec_void)\r
{\r
+ unsigned int ret_size = 0;\r
+ if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space, &ret_size))\r
+ return 0;\r
if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, ret_size))\r
return 0;\r
}\r
{\r
slang_assembly_flow_control flow;\r
\r
- if (i == 0 && assignment)\r
+ if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||\r
+ fun->parameters->variables[i].type.qualifier == slang_qual_out)\r
{\r
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
return 0;\r
/* TODO: optimize the "out" parameter case */\r
/* TODO: inspect stk */\r
- if (!_slang_assemble_operation (file, params, 1, &flow, space, info, &stk))\r
+ if (!_slang_assemble_operation (file, params + i, 1, &flow, space, info, &stk))\r
return 0;\r
if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
return 0;\r
if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
return 0;\r
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
- return 0;\r
- if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
- return 0;\r
+ if (i == 0 && assignment)\r
+ {\r
+ if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,\r
+ 4))\r
+ return 0;\r
+ if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
+ return 0;\r
+ }\r
if (!dereference (file, params, space, info))\r
return 0;\r
}\r
/* pop the parameters from the stack */\r
for (i = param_count; i > 0; i--)\r
{\r
- /* XXX: copy inout/out params back to the actual variables */\r
- if (!_slang_cleanup_stack (file, params + i - 1, 0, space))\r
- return 0;\r
+ unsigned int j = i - 1;\r
+ if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||\r
+ fun->parameters->variables[j].type.qualifier == slang_qual_out)\r
+ {\r
+ if (!_slang_assemble_assignment (file, params + j, space, info))\r
+ return 0;\r
+ if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ if (!_slang_cleanup_stack (file, params + j, 0, space))\r
+ return 0;\r
+ }\r
}\r
\r
return 1;\r
}\r
\r
-static int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,\r
+int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,\r
unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
slang_assembly_local_info *info)\r
{\r
\r
return 1;\r
}\r
-/* XXX: general swizzle! */\r
-static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
- unsigned int *index, unsigned int size, slang_assembly_local_info *info)\r
-{\r
- unsigned int i;\r
\r
- for (i = 0; i < agg->count; i++)\r
- {\r
- const slang_storage_array *arr = agg->arrays + i;\r
- unsigned int j;\r
-\r
- for (j = 0; j < arr->length; j++)\r
- {\r
- if (arr->type == slang_stor_aggregate)\r
- {\r
- if (!assign_aggregate (file, arr->aggregate, index, size, info))\r
- return 0;\r
- }\r
- else\r
- {\r
- switch (arr->type)\r
- {\r
- case slang_stor_bool:\r
- if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy,\r
- size - *index, *index))\r
- return 0;\r
- break;\r
- case slang_stor_int:\r
- if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy,\r
- size - *index, *index))\r
- return 0;\r
- break;\r
- case slang_stor_float:\r
- if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy,\r
- size - *index, *index))\r
- return 0;\r
- break;\r
- }\r
- *index += 4;\r
- }\r
- }\r
- }\r
- return 1;\r
-}\r
-/* XXX: general swizzle! */\r
-static int assignment (slang_assembly_file *file, slang_operation *op,\r
- slang_assembly_name_space *space, slang_assembly_local_info *info)\r
-{\r
- slang_assembly_typeinfo ti;\r
- int result;\r
- slang_storage_aggregate agg;\r
- unsigned int index, size;\r
-\r
- slang_assembly_typeinfo_construct (&ti);\r
- if (!_slang_typeof_operation (op, space, &ti))\r
- {\r
- slang_assembly_typeinfo_destruct (&ti);\r
- return 0;\r
- }\r
-\r
- slang_storage_aggregate_construct (&agg);\r
- if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))\r
- {\r
- slang_storage_aggregate_destruct (&agg);\r
- slang_assembly_typeinfo_destruct (&ti);\r
- return 0;\r
- }\r
-\r
- index = 0;\r
- size = _slang_sizeof_aggregate (&agg);\r
- result = assign_aggregate (file, &agg, &index, size, info);\r
-\r
- slang_storage_aggregate_destruct (&agg);\r
- slang_assembly_typeinfo_destruct (&ti);\r
- return result;\r
-}\r
/* XXX: general swizzle! */\r
static int equality_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
unsigned int *index, unsigned int size, slang_assembly_local_info *info, unsigned int z_label)\r
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
return 0;\r
/* TODO: inspect stk */\r
- if (!assignment (file, op->children, space, info))\r
+ if (!_slang_assemble_assignment (file, op->children, space, info))\r
return 0;\r
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
return 0;\r
if (var == NULL)\r
return 0;\r
size = 0;\r
- if (!sizeof_variable (&var->type.specifier, var->array_size, space, &size))\r
+ if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space,\r
+ &size))\r
return 0;\r
if (var->initializer != NULL)\r
{\r
}\r
break;\r
case slang_oper_assign:\r
- {\r
- slang_assembly_stack_info stk;\r
- if (!reference)\r
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,\r
- 4))\r
- return 0;\r
- if (!_slang_assemble_operation (file, op->children, 1, flow, space, info, &stk))\r
- return 0;\r
- /* TODO: inspect stk */\r
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
- return 0;\r
- /* TODO: inspect stk */\r
- if (!assignment (file, op->children, space, info))\r
- return 0;\r
- if (!reference)\r
- {\r
- if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
- return 0;\r
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
- return 0;\r
- if (!dereference (file, op->children, space, info))\r
- return 0;\r
- }\r
- }\r
+ if (!_slang_assemble_assign (file, op, "=", reference, space, info))\r
+ return 0;\r
break;\r
case slang_oper_addassign:\r
- /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
- if (!call_function_name (file, "+=", op->children, 2, 1, space, info))\r
+ if (!_slang_assemble_assign (file, op, "+=", reference, space, info))\r
return 0;\r
- if (reference)\r
- {\r
- /* TODO: stack is address */\r
- }\r
- else\r
- {\r
- if (!dereference (file, op->children, space, info))\r
- return 0;\r
- /* TODO: stack is operation type */\r
- }\r
break;\r
case slang_oper_subassign:\r
- /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
- if (!call_function_name (file, "-=", op->children, 2, 1, space, info))\r
+ if (!_slang_assemble_assign (file, op, "-=", reference, space, info))\r
return 0;\r
- if (reference)\r
- {\r
- /* TODO: stack is address */\r
- }\r
- else\r
- {\r
- if (!dereference (file, op->children, space, info))\r
- return 0;\r
- /* TODO: stack is operation type */\r
- }\r
break;\r
case slang_oper_mulassign:\r
- /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
- if (!call_function_name (file, "*=", op->children, 2, 1, space, info))\r
+ if (!_slang_assemble_assign (file, op, "*=", reference, space, info))\r
return 0;\r
- if (reference)\r
- {\r
- /* TODO: stack is address */\r
- }\r
- else\r
- {\r
- if (!dereference (file, op->children, space, info))\r
- return 0;\r
- /* TODO: stack is operation type */\r
- }\r
break;\r
/*case slang_oper_modassign:*/\r
/*case slang_oper_lshassign:*/\r
/*case slang_oper_xorassign:*/\r
/*case slang_oper_andassign:*/\r
case slang_oper_divassign:\r
- /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
- if (!call_function_name (file, "/=", op->children, 2, 1, space, info))\r
+ if (!_slang_assemble_assign (file, op, "/=", reference, space, info))\r
return 0;\r
- if (reference)\r
- {\r
- /* TODO: stack is address */\r
- }\r
- else\r
- {\r
- if (!dereference (file, op->children, space, info))\r
- return 0;\r
- /* TODO: stack is operation type */\r
- }\r
break;\r
case slang_oper_select:\r
if (!_slang_assemble_select (file, op, flow, space, info))\r
}\r
break;\r
case slang_oper_preincrement:\r
- /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
- if (!call_function_name (file, "++", op->children, 1, 1, space, info))\r
+ if (!_slang_assemble_assign (file, op, "++", reference, space, info))\r
return 0;\r
- if (reference)\r
- {\r
- /* TODO: stack is address */\r
- }\r
- else\r
- {\r
- /* TODO: dereference */\r
- /* TODO: stack is operation type */\r
- }\r
break;\r
case slang_oper_predecrement:\r
- /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
- if (!call_function_name (file, "--", op->children, 1, 1, space, info))\r
+ if (!_slang_assemble_assign (file, op, "--", reference, space, info))\r
return 0;\r
- if (reference)\r
- {\r
- /* TODO: stack is address */\r
- }\r
- else\r
- {\r
- /* TODO: dereference */\r
- /* TODO: stack is operation type */\r
- }\r
break;\r
case slang_oper_plus:\r
if (!call_function_name (file, "+", op->children, 1, 0, space, info))\r
slang_assembly_typeinfo_destruct (&ti_arr);\r
return 0;\r
}\r
- if (!sizeof_variable (&ti_arr.spec, NULL, space, &arr_size))\r
+ if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size))\r
{\r
slang_assembly_typeinfo_destruct (&ti_arr);\r
return 0;\r
slang_assembly_typeinfo_destruct (&ti_elem);\r
return 0;\r
}\r
- if (!sizeof_variable (&ti_elem.spec, NULL, space, &elem_size))\r
+ if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size))\r
{\r
slang_assembly_typeinfo_destruct (&ti_arr);\r
slang_assembly_typeinfo_destruct (&ti_elem);\r
slang_assembly_file_push (file, slang_asm_jump);\r
}\r
\r
-void xxx_prolog (slang_assembly_file *file)\r
+void xxx_prolog (slang_assembly_file *file, unsigned int addr)\r
{\r
file->code[0].param[0] = file->count;\r
-\r
- /* allocate local storage for inout/out params */\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_label (file, slang_asm_enter, 4);\r
-\r
-/* slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);*/\r
- slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
-/* slang_assembly_file_push_literal (file, slang_asm_float_push, 16.16f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 15.15f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 14.14f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 13.13f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 12.12f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 11.11f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 10.10f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 9.9f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 8.8f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 7.7f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 6.6f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 5.5f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 4.4f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 3.3f);\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 2.2f);*/\r
- slang_assembly_file_push_literal (file, slang_asm_float_push, 1.1f);\r
-\r
- slang_assembly_file_push_label (file, slang_asm_call, file->count + 3);\r
- slang_assembly_file_push_label (file, slang_asm_local_free, 4);\r
-\r
+ slang_assembly_file_push_label (file, slang_asm_call, addr);\r
slang_assembly_file_push (file, slang_asm_exit);\r
}\r
\r
--- /dev/null
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version: 6.3\r
+ *\r
+ * Copyright (C) 2005 Brian Paul All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * \file slang_assemble_assignment.c\r
+ * slang assignment expressions assembler\r
+ * \author Michal Krol\r
+ */\r
+\r
+#include "imports.h"\r
+#include "slang_assemble_assignment.h"\r
+#include "slang_assemble_typeinfo.h"\r
+#include "slang_storage.h"\r
+#include "slang_utility.h"\r
+\r
+/*\r
+ _slang_assemble_assignment()\r
+\r
+ copies values on the stack (<component 0> to <component N-1>) to a memory\r
+ location pointed by <addr of variable>;\r
+\r
+ in:\r
+ +------------------+\r
+ | addr of variable |\r
+ +------------------+\r
+ | component N-1 |\r
+ | ... |\r
+ | component 0 |\r
+ +------------------+\r
+\r
+ out:\r
+ +------------------+\r
+ | addr of variable |\r
+ +------------------+\r
+*/\r
+/* TODO: add support for swizzle mask */\r
+static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
+ unsigned int *index, unsigned int size, slang_assembly_local_info *info)\r
+{\r
+ unsigned int i;\r
+\r
+ for (i = 0; i < agg->count; i++)\r
+ {\r
+ const slang_storage_array *arr = agg->arrays + i;\r
+ unsigned int j;\r
+\r
+ for (j = 0; j < arr->length; j++)\r
+ {\r
+ if (arr->type == slang_stor_aggregate)\r
+ {\r
+ if (!assign_aggregate (file, arr->aggregate, index, size, info))\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ slang_assembly_type ty;\r
+\r
+ switch (arr->type)\r
+ {\r
+ case slang_stor_bool:\r
+ ty = slang_asm_bool_copy;\r
+ break;\r
+ case slang_stor_int:\r
+ ty = slang_asm_int_copy;\r
+ break;\r
+ case slang_stor_float:\r
+ ty = slang_asm_float_copy;\r
+ break;\r
+ }\r
+ if (!slang_assembly_file_push_label2 (file, ty, size - *index, *index))\r
+ return 0;\r
+ *index += 4;\r
+ }\r
+ }\r
+ }\r
+ return 1;\r
+}\r
+\r
+int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,\r
+ slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+{\r
+ slang_assembly_typeinfo ti;\r
+ int result;\r
+ slang_storage_aggregate agg;\r
+ unsigned int index, size;\r
+\r
+ slang_assembly_typeinfo_construct (&ti);\r
+ if (!_slang_typeof_operation (op, space, &ti))\r
+ {\r
+ slang_assembly_typeinfo_destruct (&ti);\r
+ return 0;\r
+ }\r
+\r
+ slang_storage_aggregate_construct (&agg);\r
+ if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))\r
+ {\r
+ slang_storage_aggregate_destruct (&agg);\r
+ slang_assembly_typeinfo_destruct (&ti);\r
+ return 0;\r
+ }\r
+\r
+ index = 0;\r
+ size = _slang_sizeof_aggregate (&agg);\r
+ result = assign_aggregate (file, &agg, &index, size, info);\r
+\r
+ slang_storage_aggregate_destruct (&agg);\r
+ slang_assembly_typeinfo_destruct (&ti);\r
+ return result;\r
+}\r
+\r
+/*\r
+ _slang_assemble_assign()\r
+\r
+ performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's\r
+ children\r
+*/\r
+\r
+int dereference (slang_assembly_file *file, slang_operation *op,\r
+ slang_assembly_name_space *space, slang_assembly_local_info *info);\r
+\r
+int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,\r
+ unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
+ slang_assembly_local_info *info);\r
+\r
+int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,\r
+ int ref, slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+{\r
+ slang_assembly_stack_info stk;\r
+ slang_assembly_flow_control flow;\r
+\r
+ if (!ref)\r
+ {\r
+ if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+ return 0;\r
+ }\r
+\r
+ if (slang_string_compare ("=", oper) == 0)\r
+ {\r
+ if (!_slang_assemble_operation (file, op->children, 1, &flow, space, info, &stk))\r
+ return 0;\r
+ if (!_slang_assemble_operation (file, op->children + 1, 0, &flow, space, info, &stk))\r
+ return 0;\r
+ if (!_slang_assemble_assignment (file, op->children, space, info))\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info))\r
+ return 0;\r
+ }\r
+\r
+ if (!ref)\r
+ {\r
+ if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
+ return 0;\r
+ if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+ return 0;\r
+ if (!dereference (file, op->children, space, info))\r
+ return 0;\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r