gambas-source-code/main/gbc/gbc_trans_expr.c

731 lines
15 KiB
C
Raw Normal View History

/***************************************************************************
gbc_trans_expr.c
(c) 2000-2009 Benoît Minisini <gambas@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
#define _TRANS_EXPR_C
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "gb_common.h"
#include "gb_error.h"
#include "gbc_compile.h"
#include "gbc_trans.h"
#include "gb_code.h"
/*#define DEBUG*/
//static bool _accept_statement = FALSE;
static short get_nparam(PATTERN *tree, int *index, uint64_t *byref)
{
PATTERN pattern;
short nparam = 0;
int shift = 0;
if (*index < (ARRAY_count(tree) - 1))
{
pattern = tree[*index + 1];
if (PATTERN_is_param(pattern))
{
(*index)++;
nparam = (short)PATTERN_index(pattern);
}
if (byref)
*byref = 0;
while (*index < (ARRAY_count(tree) - 1))
{
pattern = tree[*index + 1];
if (!PATTERN_is_param(pattern))
break;
(*index)++;
if (byref)
{
*byref |= (uint64_t)PATTERN_index(pattern) << shift;
shift += 16;
}
}
}
/*
******** Merged /branches/64bits r918:1003 into /trunk [CONFIGURATION] * NEW: 64 bits port. [EXAMPLES] * BUG: Fixed the AnalogWatch example. [WIKI CGI SCRIPT] * NEW: Some little cosmetic changes. [INTERPRETER] * NEW: The extern function implementation has been redesigned and is now based on libffi, so that it works on 64 bits system. Because of a flaw in the compiler design, projects that use the Pointer datatype must be recompiled to be used on a 64 bits system. This flaw will be fixed in Gambas 3. * OPT: Put some tables into read-only memory. About 1000 bytes are saved for each running interpreter, except the first one. * BUG: Does not crash anymore if a component cannot be loaded. * NEW: Spanish translation updated. * NEW: A new interpreter API for returning a pointer. [COMPILER] * BUG: Correctly compiles LONG constants inside code. [GB.DEBUG] * BUG: Compiles and links the gb.debug components with the thread libraries. [GB.DB.SQLITE3] * BUG: Getting the primary index of a table without primary index is safe now. [GB.GTK] * BUG: Modified the GLib priority of watched descriptors, as the main loop could enter in a loop in which user interface events were not managed. * BUG: Message boxes use application title without crashing now. [GB.OPENGL] * BUG: Disable dead code. [GB.QT.EXT] * BUG: TextEdit.TextWidth and TextEdit.TextHeight were not declared as read-only properties. [GB.XML.XSLT] * BUG: XSLT class is now declared as being not creatable. git-svn-id: svn://localhost/gambas/trunk@1006 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-01-17 22:39:26 +01:00
Gère le cas on a codé un subr sans mettre de parenthèses
=> nparam = 0
*/
return nparam;
}
static void push_number(int index)
{
TRANS_NUMBER number;
TRANS_DECL decl;
if (TRANS_get_number(index, &number))
THROW(E_SYNTAX);
if (number.type == T_INTEGER)
{
CODE_push_number(number.ival);
return;
}
CLEAR(&decl);
******** Merged /branches/64bits r918:1003 into /trunk [CONFIGURATION] * NEW: 64 bits port. [EXAMPLES] * BUG: Fixed the AnalogWatch example. [WIKI CGI SCRIPT] * NEW: Some little cosmetic changes. [INTERPRETER] * NEW: The extern function implementation has been redesigned and is now based on libffi, so that it works on 64 bits system. Because of a flaw in the compiler design, projects that use the Pointer datatype must be recompiled to be used on a 64 bits system. This flaw will be fixed in Gambas 3. * OPT: Put some tables into read-only memory. About 1000 bytes are saved for each running interpreter, except the first one. * BUG: Does not crash anymore if a component cannot be loaded. * NEW: Spanish translation updated. * NEW: A new interpreter API for returning a pointer. [COMPILER] * BUG: Correctly compiles LONG constants inside code. [GB.DEBUG] * BUG: Compiles and links the gb.debug components with the thread libraries. [GB.DB.SQLITE3] * BUG: Getting the primary index of a table without primary index is safe now. [GB.GTK] * BUG: Modified the GLib priority of watched descriptors, as the main loop could enter in a loop in which user interface events were not managed. * BUG: Message boxes use application title without crashing now. [GB.OPENGL] * BUG: Disable dead code. [GB.QT.EXT] * BUG: TextEdit.TextWidth and TextEdit.TextHeight were not declared as read-only properties. [GB.XML.XSLT] * BUG: XSLT class is now declared as being not creatable. git-svn-id: svn://localhost/gambas/trunk@1006 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-01-17 22:39:26 +01:00
decl.type = TYPE_make(number.type, 0, 0);
decl.index = NO_SYMBOL;
decl.value = index;
******** Merged /branches/64bits r918:1003 into /trunk [CONFIGURATION] * NEW: 64 bits port. [EXAMPLES] * BUG: Fixed the AnalogWatch example. [WIKI CGI SCRIPT] * NEW: Some little cosmetic changes. [INTERPRETER] * NEW: The extern function implementation has been redesigned and is now based on libffi, so that it works on 64 bits system. Because of a flaw in the compiler design, projects that use the Pointer datatype must be recompiled to be used on a 64 bits system. This flaw will be fixed in Gambas 3. * OPT: Put some tables into read-only memory. About 1000 bytes are saved for each running interpreter, except the first one. * BUG: Does not crash anymore if a component cannot be loaded. * NEW: Spanish translation updated. * NEW: A new interpreter API for returning a pointer. [COMPILER] * BUG: Correctly compiles LONG constants inside code. [GB.DEBUG] * BUG: Compiles and links the gb.debug components with the thread libraries. [GB.DB.SQLITE3] * BUG: Getting the primary index of a table without primary index is safe now. [GB.GTK] * BUG: Modified the GLib priority of watched descriptors, as the main loop could enter in a loop in which user interface events were not managed. * BUG: Message boxes use application title without crashing now. [GB.OPENGL] * BUG: Disable dead code. [GB.QT.EXT] * BUG: TextEdit.TextWidth and TextEdit.TextHeight were not declared as read-only properties. [GB.XML.XSLT] * BUG: XSLT class is now declared as being not creatable. git-svn-id: svn://localhost/gambas/trunk@1006 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-01-17 22:39:26 +01:00
if (number.type == T_LONG)
decl.lvalue = number.lval;
CODE_push_const(CLASS_add_constant(JOB->class, &decl));
}
static void push_string(int index, bool trans)
{
TRANS_DECL decl;
SYMBOL *sym;
int len;
sym = TABLE_get_symbol(JOB->class->string, index);
len = sym->len;
if (len == 0)
{
CODE_push_void_string();
}
else if (len == 1 && !trans)
{
CODE_push_char(*(sym->name));
}
else
{
CLEAR(&decl);
if (trans)
decl.type = TYPE_make(T_CSTRING, 0, 0);
else
decl.type = TYPE_make(T_STRING, 0, 0);
decl.index = NO_SYMBOL;
decl.value = index;
CODE_push_const(CLASS_add_constant(JOB->class, &decl));
}
}
void TRANS_class(int index)
{
const char *name;
if (CLASS_exist_class(JOB->class, index))
CODE_push_class(CLASS_add_class(JOB->class, index));
else
{
name = TABLE_get_symbol_name(JOB->class->table, index);
THROW("Unknown identifier: &1", name);
}
}
static void trans_identifier(int index, bool first, bool point, PATTERN next)
{
CLASS_SYMBOL *sym = CLASS_get_symbol(JOB->class, index);
bool is_static;
bool is_func;
int type;
CONSTANT *constant;
if (!TYPE_is_null(sym->local.type) && !point)
{
CODE_push_local(sym->local.value);
}
else if (!TYPE_is_null(sym->global.type) && !point)
{
type = TYPE_get_kind(sym->global.type);
if (type == TK_CONST)
{
if (PATTERN_is_point(next))
goto __CLASS;
constant = &JOB->class->constant[sym->global.value];
type = TYPE_get_id(constant->type);
if (type == T_BOOLEAN)
CODE_push_boolean(constant->value);
else if (type == T_INTEGER)
CODE_push_number(constant->value);
else
CODE_push_const(sym->global.value);
}
else if (type == TK_EXTERN)
{
if (PATTERN_is_point(next))
goto __CLASS;
CODE_push_extern(sym->global.value);
}
/* That breaks some code if the property has the same name as a class!
else if (type == TK_PROPERTY)
{
CODE_push_me(FALSE);
CODE_push_unknown(CLASS_add_unknown(JOB->class, index));
}*/
else if (type == TK_EVENT || type == TK_LABEL || type == TK_PROPERTY)
{
goto __CLASS;
}
else /* TK_FUNCTION || TK_VARIABLE */
{
is_static = TYPE_is_static(sym->global.type);
is_func = type == TK_FUNCTION;
if (!is_static && TYPE_is_static(JOB->func->type))
THROW("Dynamic symbols cannot be used in static function");
if (is_func && PATTERN_is_point(next))
goto __CLASS;
else
CODE_push_global(sym->global.value, is_static, is_func);
}
}
else
{
/*index = CLASS_add_symbol(JOB->class, index);*/
if (point)
CODE_push_unknown(CLASS_add_unknown(JOB->class, index));
/* Class must be declared now ! */
else
goto __CLASS;
}
return;
__CLASS:
TRANS_class(index);
}
static void trans_subr(int subr, short nparam)
{
SUBR_INFO *info = &COMP_subr_info[subr];
if (subr == SUBR_VarPtr)
{
if (CODE_check_varptr())
THROW("VarPtr() argument must be a dynamic, a static or a local variable");
}
if (nparam < info->min_param)
THROW("Not enough arguments to &1()", info->name);
else if (nparam > info->max_param)
THROW("Too many arguments to &1()", info->name);
CODE_subr(info->opcode, nparam, info->optype, FALSE /* output */, (info->max_param == info->min_param));
}
static void trans_operation(short op, short nparam, PATTERN previous)
{
COMP_INFO *info = &COMP_res_info[op];
switch (info->value)
{
case OP_PT:
if (nparam == 0)
TRANS_use_with();
else if (!PATTERN_is_identifier(previous))
THROW(E_SYNTAX);
break;
case OP_EXCL:
if (!PATTERN_is_identifier(previous))
THROW(E_SYNTAX);
break;
case OP_LSQR:
CODE_push_array(nparam);
break;
case OP_RSQR:
TRANS_subr(TS_SUBR_ARRAY, nparam);
break;
case OP_COLON:
TRANS_subr(TS_SUBR_COLLECTION, nparam);
break;
case OP_MINUS:
if (nparam == 1)
CODE_op(C_NEG, 0, nparam, TRUE);
else
CODE_op(info->code, info->subcode, nparam, TRUE);
break;
default:
CODE_op(info->code, info->subcode, nparam, (info->flag != RSF_OPN));
}
}
static void trans_call(short nparam, uint64_t byref)
{
if (!byref)
{
CODE_call(nparam);
return;
}
CODE_call_byref(nparam, byref);
}
static void trans_expr_from_tree(TRANS_TREE *tree)
{
int i, op;
short nparam;
int count;
PATTERN pattern, next_pattern, prev_pattern;
uint64_t byref;
count = ARRAY_count(tree) - 1;
pattern = NULL_PATTERN;
for (i = 0; i <= count; i++)
{
prev_pattern = pattern;
pattern = tree[i];
if (i < count)
next_pattern = tree[i + 1];
else
next_pattern = NULL_PATTERN;
if (PATTERN_is_number(pattern))
push_number(PATTERN_index(pattern));
else if (PATTERN_is_string(pattern))
push_string(PATTERN_index(pattern), FALSE);
else if (PATTERN_is_tstring(pattern))
push_string(PATTERN_index(pattern), TRUE);
else if (PATTERN_is_identifier(pattern))
trans_identifier(PATTERN_index(pattern), PATTERN_is_first(pattern), PATTERN_is_point(pattern), next_pattern);
else if (PATTERN_is_class(pattern))
TRANS_class(PATTERN_index(pattern));
else if (PATTERN_is_subr(pattern))
{
nparam = get_nparam(tree, &i, NULL);
trans_subr(PATTERN_index(pattern), nparam);
}
else if (PATTERN_is_reserved(pattern))
{
if (PATTERN_is(pattern, RS_TRUE))
{
CODE_push_boolean(TRUE);
}
else if (PATTERN_is(pattern, RS_FALSE))
{
CODE_push_boolean(FALSE);
}
else if (PATTERN_is(pattern, RS_NULL))
{
CODE_push_null();
}
else if (PATTERN_is(pattern, RS_ME))
{
/*if (FUNCTION_is_static(JOB->func))
THROW("ME cannot be used in a static function");*/
CODE_push_me(FALSE);
}
else if (PATTERN_is(pattern, RS_SUPER))
{
/*if (FUNCTION_is_static(JOB->func))
THROW("ME cannot be used in a static function");*/
CODE_push_super(FALSE);
}
else if (PATTERN_is(pattern, RS_LAST))
{
CODE_push_last();
}
else if (PATTERN_is(pattern, RS_AT))
{
if (!CODE_popify_last())
THROW("This expression cannot be passed by reference");
}
else if (PATTERN_is(pattern, RS_COMMA))
{
CODE_drop();
}
else if (PATTERN_is(pattern, RS_ERROR))
{
TRANS_subr(TS_SUBR_ERROR, 0);
}
else if (PATTERN_is(pattern, RS_OPTIONAL))
{
CODE_push_void();
}
else
{
op = PATTERN_index(pattern);
if (op == RS_LBRA)
{
nparam = get_nparam(tree, &i, &byref);
trans_call(nparam, byref);
}
else
{
nparam = get_nparam(tree, &i, NULL);
trans_operation((short)op, nparam, prev_pattern);
}
}
}
}
}
void TRANS_new(void)
{
int index;
int i, nparam;
bool array = FALSE;
bool event = FALSE;
bool collection = FALSE;
bool check_param = FALSE;
nparam = 0;
if (PATTERN_is_class(*JOB->current))
{
index = CLASS_add_class(JOB->class, PATTERN_index(*JOB->current));
if (PATTERN_is(JOB->current[1], RS_LSQR))
index = CLASS_get_array_class(JOB->class, T_OBJECT, index);
CODE_push_class(index);
nparam = 1;
}
else if (PATTERN_is_type(*JOB->current))
{
if (!PATTERN_is(JOB->current[1], RS_LSQR))
THROW("Cannot instanciate native types");
//CODE_push_number(RES_get_type(PATTERN_index(*JOB->current)));
CODE_push_class(CLASS_get_array_class(JOB->class, RES_get_type(PATTERN_index(*JOB->current)), -1));
nparam = 1;
}
else if (PATTERN_is(*JOB->current, RS_LBRA))
{
/* NEW ("Class", ...) */
nparam = 0;
JOB->current--;
check_param = TRUE;
}
else
THROW(E_SYNTAX);
JOB->current++;
[DEVELOPMENT ENVIRONMENT] * NEW: Work continues on integrating the database manager. * NEW: Some cosmetic changes in the way controls are drawing on the form editor. * NEW: Panels with Border property set to None are now drawn with a light border. * BUG: Fix the "Show tab" button and menu. [INTERPRETER] * NEW: _attach is a new dynamic special method that is called when an object is attached to or detached from its event observer. The first argument of this method is the event observer, and the second argument the event handler prefix. [COMPILER] * NEW: An expression can be a NEW instruction now. Beware that it does not work inside braces. [GB.DB] * BUG: Fix an error message in the sqlite handler. [GB.DB.FORM] * NEW: DataSource.Table can now be any SQL query. The Filter property is ignored in that case. * BUG: Setting DataSource.Table to NULL correctly resets the DataSource and its children. * NEW: DataView automatically adjusts the height of its rows to the contents. * NEW: DataSource.CacheSize is a new property to set the number of rows stored in the internal DataSource cache. When this property is set to zero, the cache size takes its default value (64 rows). [GB.DB.SQLITE2] * BUG: Fix a crash in datatype mapping. [GB.DB.SQLITE3] * BUG: Fix a crash in datatype mapping. [GB.QT4] * BUG: Window.AutoResize property works as expected now. * OPT: Some optimizations in GridView. * NEW: GridView.Rows[].Visible returns if a specific row is visible. * NEW: GridView.Rows[].EnsureVisible ensures that a specific row is visible. * BUG: Draw.Style.Panel draws the same thing as a panel border now. * BUG: Window.Closed always returns the accurate value now. git-svn-id: svn://localhost/gambas/trunk@2108 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-07-12 23:49:13 +02:00
if (TRANS_is(RS_LSQR))
{
if (collection)
THROW("Array declaration is forbidden with typed collection");
if (!PATTERN_is(*JOB->current, RS_RSQR))
{
for (i = 0;; i++)
{
if (i > MAX_ARRAY_DIM)
THROW("Too many dimensions");
TRANS_expression(FALSE);
nparam++;
if (PATTERN_is(*JOB->current, RS_RSQR))
break;
if (!PATTERN_is(*JOB->current, RS_COMMA))
THROW(E_MISSING, "']'");
JOB->current++;
}
}
JOB->current++;
array = TRUE;
}
else
{
[DEVELOPMENT ENVIRONMENT] * NEW: Work continues on integrating the database manager. * NEW: Some cosmetic changes in the way controls are drawing on the form editor. * NEW: Panels with Border property set to None are now drawn with a light border. * BUG: Fix the "Show tab" button and menu. [INTERPRETER] * NEW: _attach is a new dynamic special method that is called when an object is attached to or detached from its event observer. The first argument of this method is the event observer, and the second argument the event handler prefix. [COMPILER] * NEW: An expression can be a NEW instruction now. Beware that it does not work inside braces. [GB.DB] * BUG: Fix an error message in the sqlite handler. [GB.DB.FORM] * NEW: DataSource.Table can now be any SQL query. The Filter property is ignored in that case. * BUG: Setting DataSource.Table to NULL correctly resets the DataSource and its children. * NEW: DataView automatically adjusts the height of its rows to the contents. * NEW: DataSource.CacheSize is a new property to set the number of rows stored in the internal DataSource cache. When this property is set to zero, the cache size takes its default value (64 rows). [GB.DB.SQLITE2] * BUG: Fix a crash in datatype mapping. [GB.DB.SQLITE3] * BUG: Fix a crash in datatype mapping. [GB.QT4] * BUG: Window.AutoResize property works as expected now. * OPT: Some optimizations in GridView. * NEW: GridView.Rows[].Visible returns if a specific row is visible. * NEW: GridView.Rows[].EnsureVisible ensures that a specific row is visible. * BUG: Draw.Style.Panel draws the same thing as a panel border now. * BUG: Window.Closed always returns the accurate value now. git-svn-id: svn://localhost/gambas/trunk@2108 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-07-12 23:49:13 +02:00
if (TRANS_is(RS_LBRA))
{
for(;;)
{
if (nparam > MAX_PARAM_FUNC)
THROW("Too many arguments");
[DEVELOPMENT ENVIRONMENT] * BUG: Use TextEdit.RichText insted of TextEdit.Text. * BUG: END SUB can be the end of a method. The class analyze now takes   that into account. [HELP] * BUG: Fixed the generated treeview. [COMPILER] * OPT: The NOT operator used just at the beginning of a conditional expression is optimized. Consequently, an expression like 'IF NOT 2' is now equivalent to 'IF 2 = 0' and not to 'IF (NOT 2) <> 0' as before. In other words, the boolean conversion is now done before the NOT, and not after. The following instructions are concerned: IF, WHILE, UNTIL. * NEW: BYREF is new keyword that is a more readable synonymous of '@'. [GB.DB.FORM] * BUG: Correctly manage data controls inside TabStrip-like containers. * BUG: Setting the focus on a non-initialized DataControl does not raise an error anymore. [GB.GTK] * BUG: HSplitter.Layout and VSplitter.Layout now work correctly. It is a list of children widths, hidden children having a zero width. * BUG: Window arrangement is done before the Open event is raised, as in gb.qt. * BUG: Keyboard, focus and mouse events now work correctly on Window and DrawingArea controls. [GB.QT] * BUG: HSplitter.Layout and VSplitter.Layout now work correctly. It is a list of children widths, hidden children having a zero width. * BUG: Many warning fixes. * BUG: Now the Control.Visible property works like in gb.gtk, i.e. it returns if the control was not explicitely hidden. git-svn-id: svn://localhost/gambas/trunk@1060 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-02-06 01:25:48 +01:00
if (PATTERN_is(*JOB->current, RS_AT) || PATTERN_is(*JOB->current, RS_BYREF))
THROW("NEW cannot have arguments passed by reference");
TRANS_expression(FALSE);
nparam++;
if (PATTERN_is(*JOB->current, RS_RBRA))
break;
if (!PATTERN_is(*JOB->current, RS_COMMA))
THROW(E_MISSING, "')'");
JOB->current++;
}
JOB->current++;
if (check_param && nparam == 0)
THROW("Not enough argument to New()");
}
[DEVELOPMENT ENVIRONMENT] * NEW: Work continues on integrating the database manager. * NEW: Some cosmetic changes in the way controls are drawing on the form editor. * NEW: Panels with Border property set to None are now drawn with a light border. * BUG: Fix the "Show tab" button and menu. [INTERPRETER] * NEW: _attach is a new dynamic special method that is called when an object is attached to or detached from its event observer. The first argument of this method is the event observer, and the second argument the event handler prefix. [COMPILER] * NEW: An expression can be a NEW instruction now. Beware that it does not work inside braces. [GB.DB] * BUG: Fix an error message in the sqlite handler. [GB.DB.FORM] * NEW: DataSource.Table can now be any SQL query. The Filter property is ignored in that case. * BUG: Setting DataSource.Table to NULL correctly resets the DataSource and its children. * NEW: DataView automatically adjusts the height of its rows to the contents. * NEW: DataSource.CacheSize is a new property to set the number of rows stored in the internal DataSource cache. When this property is set to zero, the cache size takes its default value (64 rows). [GB.DB.SQLITE2] * BUG: Fix a crash in datatype mapping. [GB.DB.SQLITE3] * BUG: Fix a crash in datatype mapping. [GB.QT4] * BUG: Window.AutoResize property works as expected now. * OPT: Some optimizations in GridView. * NEW: GridView.Rows[].Visible returns if a specific row is visible. * NEW: GridView.Rows[].EnsureVisible ensures that a specific row is visible. * BUG: Draw.Style.Panel draws the same thing as a panel border now. * BUG: Window.Closed always returns the accurate value now. git-svn-id: svn://localhost/gambas/trunk@2108 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-07-12 23:49:13 +02:00
if (TRANS_is(RS_AS))
{
TRANS_expression(FALSE);
nparam++;
event = TRUE;
}
/*
CODE_call(nparam, FALSE);
CODE_drop();
*/
}
if (collection)
CODE_new(nparam, TRUE, event);
else
CODE_new(nparam, array, event);
}
void TRANS_expression(bool check_statement)
{
TRANS_TREE *tree;
[DEVELOPMENT ENVIRONMENT] * NEW: Work continues on integrating the database manager. * NEW: Some cosmetic changes in the way controls are drawing on the form editor. * NEW: Panels with Border property set to None are now drawn with a light border. * BUG: Fix the "Show tab" button and menu. [INTERPRETER] * NEW: _attach is a new dynamic special method that is called when an object is attached to or detached from its event observer. The first argument of this method is the event observer, and the second argument the event handler prefix. [COMPILER] * NEW: An expression can be a NEW instruction now. Beware that it does not work inside braces. [GB.DB] * BUG: Fix an error message in the sqlite handler. [GB.DB.FORM] * NEW: DataSource.Table can now be any SQL query. The Filter property is ignored in that case. * BUG: Setting DataSource.Table to NULL correctly resets the DataSource and its children. * NEW: DataView automatically adjusts the height of its rows to the contents. * NEW: DataSource.CacheSize is a new property to set the number of rows stored in the internal DataSource cache. When this property is set to zero, the cache size takes its default value (64 rows). [GB.DB.SQLITE2] * BUG: Fix a crash in datatype mapping. [GB.DB.SQLITE3] * BUG: Fix a crash in datatype mapping. [GB.QT4] * BUG: Window.AutoResize property works as expected now. * OPT: Some optimizations in GridView. * NEW: GridView.Rows[].Visible returns if a specific row is visible. * NEW: GridView.Rows[].EnsureVisible ensures that a specific row is visible. * BUG: Draw.Style.Panel draws the same thing as a panel border now. * BUG: Window.Closed always returns the accurate value now. git-svn-id: svn://localhost/gambas/trunk@2108 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-07-12 23:49:13 +02:00
if (TRANS_is(RS_NEW))
{
TRANS_new();
return;
}
else if (TRANS_is(RS_READ))
{
TRANS_read();
return;
}
[DEVELOPMENT ENVIRONMENT] * NEW: Work continues on integrating the database manager. * NEW: Some cosmetic changes in the way controls are drawing on the form editor. * NEW: Panels with Border property set to None are now drawn with a light border. * BUG: Fix the "Show tab" button and menu. [INTERPRETER] * NEW: _attach is a new dynamic special method that is called when an object is attached to or detached from its event observer. The first argument of this method is the event observer, and the second argument the event handler prefix. [COMPILER] * NEW: An expression can be a NEW instruction now. Beware that it does not work inside braces. [GB.DB] * BUG: Fix an error message in the sqlite handler. [GB.DB.FORM] * NEW: DataSource.Table can now be any SQL query. The Filter property is ignored in that case. * BUG: Setting DataSource.Table to NULL correctly resets the DataSource and its children. * NEW: DataView automatically adjusts the height of its rows to the contents. * NEW: DataSource.CacheSize is a new property to set the number of rows stored in the internal DataSource cache. When this property is set to zero, the cache size takes its default value (64 rows). [GB.DB.SQLITE2] * BUG: Fix a crash in datatype mapping. [GB.DB.SQLITE3] * BUG: Fix a crash in datatype mapping. [GB.QT4] * BUG: Window.AutoResize property works as expected now. * OPT: Some optimizations in GridView. * NEW: GridView.Rows[].Visible returns if a specific row is visible. * NEW: GridView.Rows[].EnsureVisible ensures that a specific row is visible. * BUG: Draw.Style.Panel draws the same thing as a panel border now. * BUG: Window.Closed always returns the accurate value now. git-svn-id: svn://localhost/gambas/trunk@2108 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-07-12 23:49:13 +02:00
tree = TRANS_tree(check_statement);
trans_expr_from_tree(tree);
ARRAY_delete(&tree);
if (check_statement)
{
/*
if (!CODE_check_statement_last())
THROW("This expression cannot be a statement");
*/
CODE_drop();
}
}
void TRANS_ignore_expression()
{
TRANS_TREE *tree = TRANS_tree(FALSE);
ARRAY_delete(&tree);
}
TYPE TRANS_variable_get_type()
{
TYPE type = TYPE_make(T_NULL, 0, 0);
TRANS_TREE *tree = TRANS_tree(FALSE);
int index;
CLASS_SYMBOL *sym;
if (ARRAY_count(tree) == 1 && PATTERN_is_identifier(*tree))
{
index = PATTERN_index(*tree);
sym = CLASS_get_symbol(JOB->class, index);
if (!TYPE_is_null(sym->local.type))
{
return sym->local.type;
}
else if (!TYPE_is_null(sym->global.type))
{
int type = TYPE_get_kind(sym->global.type);
if (type == TK_VARIABLE)
return sym->global.type;
}
}
ARRAY_delete(&tree);
return type;
}
void TRANS_reference(void)
{
TRANS_expression(FALSE);
if (!CODE_popify_last())
THROW("Invalid assignment");
}
bool TRANS_affectation(bool dup)
{
static TRANS_STATEMENT statement[] = {
//{ RS_NEW, TRANS_new },
{ RS_OPEN, TRANS_open },
{ RS_SHELL, TRANS_shell },
{ RS_EXEC, TRANS_exec },
{ RS_RAISE, TRANS_raise },
{ RS_PIPE, TRANS_pipe },
{ RS_LOCK, TRANS_lock },
{ RS_MEMORY, TRANS_memory },
//{ RS_READ, TRANS_read },
{ RS_NONE, NULL }
};
TRANS_STATEMENT *st;
PATTERN *look = JOB->current;
PATTERN *left, *expr, *after;
int niv = 0;
bool equal = FALSE;
bool stat = FALSE;
int op;
for(;;)
{
if (PATTERN_is_newline(*look) || PATTERN_is_end(*look))
break;
if (PATTERN_is(*look, RS_LBRA) || PATTERN_is(*look, RS_LSQR))
{
niv++;
}
else if (PATTERN_is(*look, RS_RBRA) || PATTERN_is(*look, RS_RSQR))
{
if (niv > 0)
niv--;
}
else if (niv == 0)
{
if (PATTERN_is(*look, RS_EQUAL))
{
equal = TRUE;
op = RS_NONE;
break;
}
else if (PATTERN_is_reserved(*look) && RES_is_assignment(PATTERN_index(*look)))
{
equal = TRUE;
op = RES_get_assignment_operator(PATTERN_index(*look));
break;
}
}
look++;
}
if (!equal)
return FALSE;
left = JOB->current;
*look++ = PATTERN_make(RT_NEWLINE, 0);
expr = look;
JOB->current = expr;
if (op == RS_NONE && (PATTERN_is_reserved(*JOB->current)))
{
[DEVELOPMENT ENVIRONMENT] * NEW: Work continues on integrating the database manager. * NEW: Some cosmetic changes in the way controls are drawing on the form editor. * NEW: Panels with Border property set to None are now drawn with a light border. * BUG: Fix the "Show tab" button and menu. [INTERPRETER] * NEW: _attach is a new dynamic special method that is called when an object is attached to or detached from its event observer. The first argument of this method is the event observer, and the second argument the event handler prefix. [COMPILER] * NEW: An expression can be a NEW instruction now. Beware that it does not work inside braces. [GB.DB] * BUG: Fix an error message in the sqlite handler. [GB.DB.FORM] * NEW: DataSource.Table can now be any SQL query. The Filter property is ignored in that case. * BUG: Setting DataSource.Table to NULL correctly resets the DataSource and its children. * NEW: DataView automatically adjusts the height of its rows to the contents. * NEW: DataSource.CacheSize is a new property to set the number of rows stored in the internal DataSource cache. When this property is set to zero, the cache size takes its default value (64 rows). [GB.DB.SQLITE2] * BUG: Fix a crash in datatype mapping. [GB.DB.SQLITE3] * BUG: Fix a crash in datatype mapping. [GB.QT4] * BUG: Window.AutoResize property works as expected now. * OPT: Some optimizations in GridView. * NEW: GridView.Rows[].Visible returns if a specific row is visible. * NEW: GridView.Rows[].EnsureVisible ensures that a specific row is visible. * BUG: Draw.Style.Panel draws the same thing as a panel border now. * BUG: Window.Closed always returns the accurate value now. git-svn-id: svn://localhost/gambas/trunk@2108 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-07-12 23:49:13 +02:00
if (TRANS_is(RS_NEW))
{
TRANS_in_affectation++;
TRANS_new();
TRANS_in_affectation--;
stat = TRUE;
}
else
{
for (st = statement; st->id; st++)
{
[DEVELOPMENT ENVIRONMENT] * NEW: Work continues on integrating the database manager. * NEW: Some cosmetic changes in the way controls are drawing on the form editor. * NEW: Panels with Border property set to None are now drawn with a light border. * BUG: Fix the "Show tab" button and menu. [INTERPRETER] * NEW: _attach is a new dynamic special method that is called when an object is attached to or detached from its event observer. The first argument of this method is the event observer, and the second argument the event handler prefix. [COMPILER] * NEW: An expression can be a NEW instruction now. Beware that it does not work inside braces. [GB.DB] * BUG: Fix an error message in the sqlite handler. [GB.DB.FORM] * NEW: DataSource.Table can now be any SQL query. The Filter property is ignored in that case. * BUG: Setting DataSource.Table to NULL correctly resets the DataSource and its children. * NEW: DataView automatically adjusts the height of its rows to the contents. * NEW: DataSource.CacheSize is a new property to set the number of rows stored in the internal DataSource cache. When this property is set to zero, the cache size takes its default value (64 rows). [GB.DB.SQLITE2] * BUG: Fix a crash in datatype mapping. [GB.DB.SQLITE3] * BUG: Fix a crash in datatype mapping. [GB.QT4] * BUG: Window.AutoResize property works as expected now. * OPT: Some optimizations in GridView. * NEW: GridView.Rows[].Visible returns if a specific row is visible. * NEW: GridView.Rows[].EnsureVisible ensures that a specific row is visible. * BUG: Draw.Style.Panel draws the same thing as a panel border now. * BUG: Window.Closed always returns the accurate value now. git-svn-id: svn://localhost/gambas/trunk@2108 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-07-12 23:49:13 +02:00
if (TRANS_is(st->id))
{
TRANS_in_affectation++;
(*st->func)();
TRANS_in_affectation--;
stat = TRUE;
}
}
}
}
if (!stat)
{
if (op != RS_NONE)
{
JOB->current = left;
TRANS_expression(FALSE);
}
JOB->current = expr;
TRANS_expression(FALSE);
after = JOB->current;
if (op != RS_NONE)
trans_operation(op, 2, NULL_PATTERN);
}
after = JOB->current;
if (dup)
CODE_dup();
JOB->current = left;
TRANS_reference();
JOB->current = after;
return TRUE;
}