diff options
Diffstat (limited to 'src/mesa/shader/slang/slang_assemble_conditional.c')
-rw-r--r-- | src/mesa/shader/slang/slang_assemble_conditional.c | 896 |
1 files changed, 448 insertions, 448 deletions
diff --git a/src/mesa/shader/slang/slang_assemble_conditional.c b/src/mesa/shader/slang/slang_assemble_conditional.c index b29d0cf..f3400e8 100644 --- a/src/mesa/shader/slang/slang_assemble_conditional.c +++ b/src/mesa/shader/slang/slang_assemble_conditional.c @@ -1,448 +1,448 @@ -/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file slang_assemble_conditional.c
- * slang condtional expressions assembler
- * \author Michal Krol
- */
-
-#include "imports.h"
-#include "slang_assemble.h"
-#include "slang_compile.h"
-
-/*
- * _slang_assemble_logicaland()
- *
- * and:
- * <left-expression>
- * jumpz zero
- * <right-expression>
- * jump end
- * zero:
- * push 0
- * end:
- */
-
-GLboolean _slang_assemble_logicaland (slang_assemble_ctx *A, slang_operation *op)
-{
- GLuint zero_jump, end_jump;
-
- /* evaluate left expression */
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to pushing 0 if not true */
- zero_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero))
- return GL_FALSE;
-
- /* evaluate right expression */
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to the end of the expression */
- end_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* push 0 on stack */
- A->file->code[zero_jump].param[0] = A->file->count;
- if (!slang_assembly_file_push_literal (A->file, slang_asm_bool_push, (GLfloat) 0))
- return GL_FALSE;
-
- /* the end of the expression */
- A->file->code[end_jump].param[0] = A->file->count;
-
- return GL_TRUE;
-}
-
-/*
- * _slang_assemble_logicalor()
- *
- * or:
- * <left-expression>
- * jumpz right
- * push 1
- * jump end
- * right:
- * <right-expression>
- * end:
- */
-
-GLboolean _slang_assemble_logicalor (slang_assemble_ctx *A, slang_operation *op)
-{
- GLuint right_jump, end_jump;
-
- /* evaluate left expression */
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to evaluation of right expression if not true */
- right_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero))
- return GL_FALSE;
-
- /* push 1 on stack */
- if (!slang_assembly_file_push_literal (A->file, slang_asm_bool_push, (GLfloat) 1))
- return GL_FALSE;
-
- /* jump to the end of the expression */
- end_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* evaluate right expression */
- A->file->code[right_jump].param[0] = A->file->count;
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
-
- /* the end of the expression */
- A->file->code[end_jump].param[0] = A->file->count;
-
- return GL_TRUE;
-}
-
-/*
- * _slang_assemble_select()
- *
- * select:
- * <condition-expression>
- * jumpz false
- * <true-expression>
- * jump end
- * false:
- * <false-expression>
- * end:
- */
-
-GLboolean _slang_assemble_select (slang_assemble_ctx *A, slang_operation *op)
-{
- GLuint cond_jump, end_jump;
-
- /* execute condition expression */
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to false expression if not true */
- cond_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero))
- return GL_FALSE;
-
- /* execute true expression */
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to the end of the expression */
- end_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* resolve false point */
- A->file->code[cond_jump].param[0] = A->file->count;
-
- /* execute false expression */
- if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid))
- return GL_FALSE;
-
- /* resolve the end of the expression */
- A->file->code[end_jump].param[0] = A->file->count;
-
- return GL_TRUE;
-}
-
-/*
- * _slang_assemble_for()
- *
- * for:
- * <init-statement>
- * jump start
- * break:
- * jump end
- * continue:
- * <loop-increment>
- * start:
- * <condition-statement>
- * jumpz end
- * <loop-body>
- * jump continue
- * end:
- */
-
-GLboolean _slang_assemble_for (slang_assemble_ctx *A, slang_operation *op)
-{
- GLuint start_jump, end_jump, cond_jump;
- GLuint break_label, cont_label;
- slang_assembly_flow_control save_flow = A->flow;
-
- /* execute initialization statement */
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[0]))
- return GL_FALSE;
-
- /* skip the "go to the end of the loop" and loop-increment statements */
- start_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* go to the end of the loop - break statements are directed here */
- break_label = A->file->count;
- end_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* resolve the beginning of the loop - continue statements are directed here */
- cont_label = A->file->count;
-
- /* execute loop-increment statement */
- if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[2]))
- return GL_FALSE;
-
- /* resolve the condition point */
- A->file->code[start_jump].param[0] = A->file->count;
-
- /* execute condition statement */
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to the end of the loop if not true */
- cond_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero))
- return GL_FALSE;
-
- /* execute loop body */
- A->flow.loop_start = cont_label;
- A->flow.loop_end = break_label;
- if (!_slang_assemble_operation (A, &op->children[3], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[3]))
- return GL_FALSE;
- A->flow = save_flow;
-
- /* go to the beginning of the loop */
- if (!slang_assembly_file_push_label (A->file, slang_asm_jump, cont_label))
- return GL_FALSE;
-
- /* resolve the end of the loop */
- A->file->code[end_jump].param[0] = A->file->count;
- A->file->code[cond_jump].param[0] = A->file->count;
-
- return GL_TRUE;
-}
-
-/*
- * _slang_assemble_do()
- *
- * do:
- * jump start
- * break:
- * jump end
- * continue:
- * jump condition
- * start:
- * <loop-body>
- * condition:
- * <condition-statement>
- * jumpz end
- * jump start
- * end:
- */
-
-GLboolean _slang_assemble_do (slang_assemble_ctx *A, slang_operation *op)
-{
- GLuint skip_jump, end_jump, cont_jump, cond_jump;
- GLuint break_label, cont_label;
- slang_assembly_flow_control save_flow = A->flow;
-
- /* skip the "go to the end of the loop" and "go to condition" statements */
- skip_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* go to the end of the loop - break statements are directed here */
- break_label = A->file->count;
- end_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* go to condition - continue statements are directed here */
- cont_label = A->file->count;
- cont_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* resolve the beginning of the loop */
- A->file->code[skip_jump].param[0] = A->file->count;
-
- /* execute loop body */
- A->flow.loop_start = cont_label;
- A->flow.loop_end = break_label;
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[0]))
- return GL_FALSE;
- A->flow = save_flow;
-
- /* resolve condition point */
- A->file->code[cont_jump].param[0] = A->file->count;
-
- /* execute condition statement */
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to the end of the loop if not true */
- cond_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero))
- return GL_FALSE;
-
- /* jump to the beginning of the loop */
- if (!slang_assembly_file_push_label (A->file, slang_asm_jump, A->file->code[skip_jump].param[0]))
- return GL_FALSE;
-
- /* resolve the end of the loop */
- A->file->code[end_jump].param[0] = A->file->count;
- A->file->code[cond_jump].param[0] = A->file->count;
-
- return GL_TRUE;
-}
-
-/*
- * _slang_assemble_while()
- *
- * while:
- * jump continue
- * break:
- * jump end
- * continue:
- * <condition-statement>
- * jumpz end
- * <loop-body>
- * jump continue
- * end:
- */
-
-GLboolean _slang_assemble_while (slang_assemble_ctx *A, slang_operation *op)
-{
- GLuint skip_jump, end_jump, cond_jump;
- GLuint break_label;
- slang_assembly_flow_control save_flow = A->flow;
-
- /* skip the "go to the end of the loop" statement */
- skip_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* go to the end of the loop - break statements are directed here */
- break_label = A->file->count;
- end_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* resolve the beginning of the loop - continue statements are directed here */
- A->file->code[skip_jump].param[0] = A->file->count;
-
- /* execute condition statement */
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to the end of the loop if not true */
- cond_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero))
- return GL_FALSE;
-
- /* execute loop body */
- A->flow.loop_start = A->file->code[skip_jump].param[0];
- A->flow.loop_end = break_label;
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[1]))
- return GL_FALSE;
- A->flow = save_flow;
-
- /* jump to the beginning of the loop */
- if (!slang_assembly_file_push_label (A->file, slang_asm_jump, A->file->code[skip_jump].param[0]))
- return GL_FALSE;
-
- /* resolve the end of the loop */
- A->file->code[end_jump].param[0] = A->file->count;
- A->file->code[cond_jump].param[0] = A->file->count;
-
- return GL_TRUE;
-}
-
-/*
- * _slang_assemble_if()
- *
- * if:
- * <condition-statement>
- * jumpz else
- * <true-statement>
- * jump end
- * else:
- * <false-statement>
- * end:
- */
-
-GLboolean _slang_assemble_if (slang_assemble_ctx *A, slang_operation *op)
-{
- GLuint cond_jump, else_jump;
-
- /* execute condition statement */
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
- return GL_FALSE;
-
- /* jump to false-statement if not true */
- cond_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero))
- return GL_FALSE;
-
- /* execute true-statement */
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[1]))
- return GL_FALSE;
-
- /* skip if-false statement */
- else_jump = A->file->count;
- if (!slang_assembly_file_push (A->file, slang_asm_jump))
- return GL_FALSE;
-
- /* resolve start of false-statement */
- A->file->code[cond_jump].param[0] = A->file->count;
-
- /* execute false-statement */
- if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[2]))
- return GL_FALSE;
-
- /* resolve end of if-false statement */
- A->file->code[else_jump].param[0] = A->file->count;
-
- return GL_TRUE;
-}
-
+/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_assemble_conditional.c + * slang condtional expressions assembler + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_assemble.h" +#include "slang_compile.h" + +/* + * _slang_assemble_logicaland() + * + * and: + * <left-expression> + * jumpz zero + * <right-expression> + * jump end + * zero: + * push 0 + * end: + */ + +GLboolean _slang_assemble_logicaland (slang_assemble_ctx *A, slang_operation *op) +{ + GLuint zero_jump, end_jump; + + /* evaluate left expression */ + if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) + return GL_FALSE; + + /* jump to pushing 0 if not true */ + zero_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) + return GL_FALSE; + + /* evaluate right expression */ + if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + + /* jump to the end of the expression */ + end_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* push 0 on stack */ + A->file->code[zero_jump].param[0] = A->file->count; + if (!slang_assembly_file_push_literal (A->file, slang_asm_bool_push, (GLfloat) 0)) + return GL_FALSE; + + /* the end of the expression */ + A->file->code[end_jump].param[0] = A->file->count; + + return GL_TRUE; +} + +/* + * _slang_assemble_logicalor() + * + * or: + * <left-expression> + * jumpz right + * push 1 + * jump end + * right: + * <right-expression> + * end: + */ + +GLboolean _slang_assemble_logicalor (slang_assemble_ctx *A, slang_operation *op) +{ + GLuint right_jump, end_jump; + + /* evaluate left expression */ + if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) + return GL_FALSE; + + /* jump to evaluation of right expression if not true */ + right_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) + return GL_FALSE; + + /* push 1 on stack */ + if (!slang_assembly_file_push_literal (A->file, slang_asm_bool_push, (GLfloat) 1)) + return GL_FALSE; + + /* jump to the end of the expression */ + end_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* evaluate right expression */ + A->file->code[right_jump].param[0] = A->file->count; + if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + + /* the end of the expression */ + A->file->code[end_jump].param[0] = A->file->count; + + return GL_TRUE; +} + +/* + * _slang_assemble_select() + * + * select: + * <condition-expression> + * jumpz false + * <true-expression> + * jump end + * false: + * <false-expression> + * end: + */ + +GLboolean _slang_assemble_select (slang_assemble_ctx *A, slang_operation *op) +{ + GLuint cond_jump, end_jump; + + /* execute condition expression */ + if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) + return GL_FALSE; + + /* jump to false expression if not true */ + cond_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) + return GL_FALSE; + + /* execute true expression */ + if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + + /* jump to the end of the expression */ + end_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* resolve false point */ + A->file->code[cond_jump].param[0] = A->file->count; + + /* execute false expression */ + if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid)) + return GL_FALSE; + + /* resolve the end of the expression */ + A->file->code[end_jump].param[0] = A->file->count; + + return GL_TRUE; +} + +/* + * _slang_assemble_for() + * + * for: + * <init-statement> + * jump start + * break: + * jump end + * continue: + * <loop-increment> + * start: + * <condition-statement> + * jumpz end + * <loop-body> + * jump continue + * end: + */ + +GLboolean _slang_assemble_for (slang_assemble_ctx *A, slang_operation *op) +{ + GLuint start_jump, end_jump, cond_jump; + GLuint break_label, cont_label; + slang_assembly_flow_control save_flow = A->flow; + + /* execute initialization statement */ + if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/)) + return GL_FALSE; + if (!_slang_cleanup_stack (A, &op->children[0])) + return GL_FALSE; + + /* skip the "go to the end of the loop" and loop-increment statements */ + start_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* go to the end of the loop - break statements are directed here */ + break_label = A->file->count; + end_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* resolve the beginning of the loop - continue statements are directed here */ + cont_label = A->file->count; + + /* execute loop-increment statement */ + if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid/*slang_ref_freelance*/)) + return GL_FALSE; + if (!_slang_cleanup_stack (A, &op->children[2])) + return GL_FALSE; + + /* resolve the condition point */ + A->file->code[start_jump].param[0] = A->file->count; + + /* execute condition statement */ + if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + + /* jump to the end of the loop if not true */ + cond_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) + return GL_FALSE; + + /* execute loop body */ + A->flow.loop_start = cont_label; + A->flow.loop_end = break_label; + if (!_slang_assemble_operation (A, &op->children[3], slang_ref_forbid/*slang_ref_freelance*/)) + return GL_FALSE; + if (!_slang_cleanup_stack (A, &op->children[3])) + return GL_FALSE; + A->flow = save_flow; + + /* go to the beginning of the loop */ + if (!slang_assembly_file_push_label (A->file, slang_asm_jump, cont_label)) + return GL_FALSE; + + /* resolve the end of the loop */ + A->file->code[end_jump].param[0] = A->file->count; + A->file->code[cond_jump].param[0] = A->file->count; + + return GL_TRUE; +} + +/* + * _slang_assemble_do() + * + * do: + * jump start + * break: + * jump end + * continue: + * jump condition + * start: + * <loop-body> + * condition: + * <condition-statement> + * jumpz end + * jump start + * end: + */ + +GLboolean _slang_assemble_do (slang_assemble_ctx *A, slang_operation *op) +{ + GLuint skip_jump, end_jump, cont_jump, cond_jump; + GLuint break_label, cont_label; + slang_assembly_flow_control save_flow = A->flow; + + /* skip the "go to the end of the loop" and "go to condition" statements */ + skip_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* go to the end of the loop - break statements are directed here */ + break_label = A->file->count; + end_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* go to condition - continue statements are directed here */ + cont_label = A->file->count; + cont_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* resolve the beginning of the loop */ + A->file->code[skip_jump].param[0] = A->file->count; + + /* execute loop body */ + A->flow.loop_start = cont_label; + A->flow.loop_end = break_label; + if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/)) + return GL_FALSE; + if (!_slang_cleanup_stack (A, &op->children[0])) + return GL_FALSE; + A->flow = save_flow; + + /* resolve condition point */ + A->file->code[cont_jump].param[0] = A->file->count; + + /* execute condition statement */ + if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + + /* jump to the end of the loop if not true */ + cond_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) + return GL_FALSE; + + /* jump to the beginning of the loop */ + if (!slang_assembly_file_push_label (A->file, slang_asm_jump, A->file->code[skip_jump].param[0])) + return GL_FALSE; + + /* resolve the end of the loop */ + A->file->code[end_jump].param[0] = A->file->count; + A->file->code[cond_jump].param[0] = A->file->count; + + return GL_TRUE; +} + +/* + * _slang_assemble_while() + * + * while: + * jump continue + * break: + * jump end + * continue: + * <condition-statement> + * jumpz end + * <loop-body> + * jump continue + * end: + */ + +GLboolean _slang_assemble_while (slang_assemble_ctx *A, slang_operation *op) +{ + GLuint skip_jump, end_jump, cond_jump; + GLuint break_label; + slang_assembly_flow_control save_flow = A->flow; + + /* skip the "go to the end of the loop" statement */ + skip_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* go to the end of the loop - break statements are directed here */ + break_label = A->file->count; + end_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* resolve the beginning of the loop - continue statements are directed here */ + A->file->code[skip_jump].param[0] = A->file->count; + + /* execute condition statement */ + if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) + return GL_FALSE; + + /* jump to the end of the loop if not true */ + cond_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) + return GL_FALSE; + + /* execute loop body */ + A->flow.loop_start = A->file->code[skip_jump].param[0]; + A->flow.loop_end = break_label; + if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid/*slang_ref_freelance*/)) + return GL_FALSE; + if (!_slang_cleanup_stack (A, &op->children[1])) + return GL_FALSE; + A->flow = save_flow; + + /* jump to the beginning of the loop */ + if (!slang_assembly_file_push_label (A->file, slang_asm_jump, A->file->code[skip_jump].param[0])) + return GL_FALSE; + + /* resolve the end of the loop */ + A->file->code[end_jump].param[0] = A->file->count; + A->file->code[cond_jump].param[0] = A->file->count; + + return GL_TRUE; +} + +/* + * _slang_assemble_if() + * + * if: + * <condition-statement> + * jumpz else + * <true-statement> + * jump end + * else: + * <false-statement> + * end: + */ + +GLboolean _slang_assemble_if (slang_assemble_ctx *A, slang_operation *op) +{ + GLuint cond_jump, else_jump; + + /* execute condition statement */ + if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) + return GL_FALSE; + + /* jump to false-statement if not true */ + cond_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) + return GL_FALSE; + + /* execute true-statement */ + if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid/*slang_ref_freelance*/)) + return GL_FALSE; + if (!_slang_cleanup_stack (A, &op->children[1])) + return GL_FALSE; + + /* skip if-false statement */ + else_jump = A->file->count; + if (!slang_assembly_file_push (A->file, slang_asm_jump)) + return GL_FALSE; + + /* resolve start of false-statement */ + A->file->code[cond_jump].param[0] = A->file->count; + + /* execute false-statement */ + if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid/*slang_ref_freelance*/)) + return GL_FALSE; + if (!_slang_cleanup_stack (A, &op->children[2])) + return GL_FALSE; + + /* resolve end of if-false statement */ + A->file->code[else_jump].param[0] = A->file->count; + + return GL_TRUE; +} + |