gbc_header.c 22.3 KB
Newer Older
1 2
/***************************************************************************

Benoît Minisini's avatar
Benoît Minisini committed
3
  gbc_header.c
4

5
  (c) 2000-2017 Benoît Minisini <[email protected]>
6

Benoît Minisini's avatar
Benoît Minisini committed
7 8 9 10
  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.
11

Benoît Minisini's avatar
Benoît Minisini committed
12 13 14 15
  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.
16

Benoît Minisini's avatar
Benoît Minisini committed
17 18 19 20
  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., 51 Franklin Street, Fifth Floor, Boston,
  MA 02110-1301, USA.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

***************************************************************************/

#define _TRANS_HEADER_C

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "gb_common.h"
#include "gb_error.h"
#include "gb_str.h"
#include "gb_file.h"
#include "gb_table.h"

#include "gbc_compile.h"
#include "gbc_trans.h"
#include "gbc_header.h"
Benoît Minisini's avatar
Benoît Minisini committed
39
#include "gb_code.h"
40 41 42 43

/*#define DEBUG*/


Benoît Minisini's avatar
Benoît Minisini committed
44 45
static void check_public_private(PATTERN **look, bool *is_public)
{
Benoît Minisini's avatar
Benoît Minisini committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
	*is_public = JOB->is_module && JOB->public_module;

	if (PATTERN_is(**look, RS_PUBLIC))
	{
		*is_public = TRUE;
		(*look)++;
	}
	else if (PATTERN_is(**look, RS_PRIVATE))
	{
		*is_public = FALSE;
		(*look)++;
	}
}

static PATTERN *jump_expression(PATTERN *look)
{
	int niv = 0;
	
	for(;;)
	{
		if (PATTERN_is_newline(*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
				break;
		}
		else if (niv == 0)
		{
			if (PATTERN_is(*look, RS_COMMA))
				break;
		}
		
		look++;
	}
	
	return look;
Benoît Minisini's avatar
Benoît Minisini committed
90 91
}

92 93
static void analyze_function_desc(TRANS_FUNC *func, int flag)
{
Benoît Minisini's avatar
Benoît Minisini committed
94 95 96 97 98 99
	PATTERN *look = JOB->current;
	TRANS_PARAM *param;
	//bool is_output;
	bool is_optional = FALSE;
	TRANS_DECL ttyp;
	uint64_t byref_mask = 1;
100

Benoît Minisini's avatar
Benoît Minisini committed
101 102
	if (!PATTERN_is_identifier(*look))
		THROW("Syntax error. Invalid identifier in function name");
103

Benoît Minisini's avatar
Benoît Minisini committed
104
	func->index = PATTERN_index(*look);
Benoît Minisini's avatar
Benoît Minisini committed
105
	TYPE_clear(&func->type);
Benoît Minisini's avatar
Benoît Minisini committed
106
	look++;
107

Benoît Minisini's avatar
Benoît Minisini committed
108
	if (flag & HF_EVENT)
109
		func->index = TABLE_copy_symbol_with_prefix(JOB->class->table, func->index, ':');
110

Benoît Minisini's avatar
Benoît Minisini committed
111 112 113
	func->nparam = 0;
	func->byref = 0;
	func->vararg = FALSE;
114

Benoît Minisini's avatar
Benoît Minisini committed
115 116 117 118 119
	if ((flag & HF_VOID) && PATTERN_is_newline(*look))
	{
		JOB->current = ++look;
		return;
	}
120

Benoît Minisini's avatar
Benoît Minisini committed
121
	if (!PATTERN_is(*look, RS_LBRA))
Benoît Minisini's avatar
Benoît Minisini committed
122
		THROW_UNEXPECTED(look);
Benoît Minisini's avatar
Benoît Minisini committed
123
	look++;
124

Benoît Minisini's avatar
Benoît Minisini committed
125 126
	for(;;)
	{
Benoît Minisini's avatar
Benoît Minisini committed
127 128 129
		if (func->nparam >= MAX_PARAM_FUNC)
			THROW("Too many arguments");

Benoît Minisini's avatar
Benoît Minisini committed
130
		param = &func->param[func->nparam];
Benoît Minisini's avatar
Benoît Minisini committed
131
		CLEAR(param);
132

Benoît Minisini's avatar
Benoît Minisini committed
133 134 135 136 137 138 139 140 141 142 143 144 145
		if (PATTERN_is(*look, RS_RBRA))
		{
			look++;
			break;
		}

		if (func->nparam > 0)
		{
			if (!PATTERN_is(*look, RS_COMMA))
				THROW(E_SYNTAX_MISSING, "',' or ')'");
			look++;
		}

Benoît Minisini's avatar
Benoît Minisini committed
146
		if (PATTERN_is(*look, RS_3PTS) && !(flag & HF_NO_3PTS))
Benoît Minisini's avatar
Benoît Minisini committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
		{
			look++;
			if (!PATTERN_is(*look, RS_RBRA))
				THROW("Syntax error. '...' must be the last argument"); //, get_num_desc(func->nparam + 1));
			look++;
			func->vararg = TRUE;
			break;
		}

		//is_output = FALSE;

		if (!(flag & HF_NO_OPT))
		{
			if (PATTERN_is(*look, RS_OPTIONAL))
			{
				look++;
				is_optional = TRUE;
			}
		}

		if (PATTERN_is(*look, RS_AT) || PATTERN_is(*look, RS_BYREF))
		{
169
			param->byref = TRUE;
Benoît Minisini's avatar
Benoît Minisini committed
170 171 172 173
			func->byref |= byref_mask;
			look++;
		}

Benoît Minisini's avatar
Benoît Minisini committed
174 175 176 177 178 179
		if (PATTERN_is(*look, RS_LBRA))
		{
			param->ignore = TRUE;
			look++;
		}
		
Benoît Minisini's avatar
Benoît Minisini committed
180 181
		if (!PATTERN_is_identifier(*look))
			THROW("Syntax error. The &1 argument is not a valid identifier", TRANS_get_num_desc(func->nparam + 1));
Benoît Minisini's avatar
Benoît Minisini committed
182
		
Benoît Minisini's avatar
Benoît Minisini committed
183 184
		param->index = PATTERN_index(*look);
		look++;
Benoît Minisini's avatar
Benoît Minisini committed
185 186 187 188 189 190 191 192
		
		if (param->ignore)
		{
			if (!PATTERN_is(*look, RS_RBRA))
				THROW(E_MISSING, "')'");
			look++;
		}

Benoît Minisini's avatar
Benoît Minisini committed
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
		JOB->current = look;

		if (!TRANS_type(TT_NOTHING, &ttyp))
			THROW("Syntax error. Invalid type description of &1 argument", TRANS_get_num_desc(func->nparam + 1));

		param->type = ttyp.type;

		/*
		if (is_output)
			TYPE_set_flag(&param->type, TF_OUTPUT);
		*/

		look = JOB->current;

		if (is_optional)
		{
			param->optional = look;
			look = jump_expression(look);
			JOB->current = look;
		}

		func->nparam++;
		byref_mask <<= 1;
	}

	JOB->current = look;
219 220 221 222 223
}


static void header_module_type(void)
{
Benoît Minisini's avatar
Benoît Minisini committed
224
	const char *ext;
Benoît Minisini's avatar
Benoît Minisini committed
225
	const FORM_FAMILY *p;
226

Benoît Minisini's avatar
Benoît Minisini committed
227
	/*JOB->class->name = STR_copy(FILE_get_name(JOB->name));*/
228

Benoît Minisini's avatar
Benoît Minisini committed
229
	ext = FILE_get_ext(JOB->name);
230

Benoît Minisini's avatar
Benoît Minisini committed
231 232 233 234 235 236 237 238 239 240 241
	if (strcasecmp(ext, "module") == 0)
	{
		JOB->is_module = TRUE;
		JOB->is_form = FALSE;
	}
	else if (strcasecmp(ext, "class") == 0)
	{
		JOB->is_module = FALSE;
		JOB->is_form = FALSE;
	}
	else
Benoît Minisini's avatar
Benoît Minisini committed
242 243
	{
		p = COMP_form_families;
Benoît Minisini's avatar
Benoît Minisini committed
244
		while (p->ext)
Benoît Minisini's avatar
Benoît Minisini committed
245
		{
Benoît Minisini's avatar
Benoît Minisini committed
246
			if (strcasecmp(ext, p->ext) == 0)
Benoît Minisini's avatar
Benoît Minisini committed
247 248 249 250 251 252 253 254
			{
				JOB->is_module = FALSE;
				JOB->is_form = TRUE;
				break;
			}
			p++;
		}
		
Benoît Minisini's avatar
Benoît Minisini committed
255
		if (!p->ext)
Benoît Minisini's avatar
Benoît Minisini committed
256 257
			THROW("Unknown file extension");
	}
258

Benoît Minisini's avatar
Benoît Minisini committed
259
	JOB->declared = TRUE;
260 261 262 263 264
}


static bool header_event(TRANS_EVENT *event)
{
Benoît Minisini's avatar
Benoît Minisini committed
265 266
	PATTERN *look = JOB->current;
	//TRANS_DECL ttyp;
267

Benoît Minisini's avatar
Benoît Minisini committed
268 269
	if (!PATTERN_is(*look, RS_EVENT))
		return FALSE;
270

Benoît Minisini's avatar
Benoît Minisini committed
271
	CLEAR(event);
272

Benoît Minisini's avatar
Benoît Minisini committed
273 274
	if (JOB->is_module)
		THROW("A module cannot raise events");
275

Benoît Minisini's avatar
Benoît Minisini committed
276
	JOB->current++;
Benoît Minisini's avatar
Benoît Minisini committed
277
	analyze_function_desc((TRANS_FUNC *)event, HF_VOID + HF_NO_BYREF + HF_NO_3PTS + HF_NO_OPT);
278

Benoît Minisini's avatar
Benoît Minisini committed
279 280 281 282 283 284
	/*if (PATTERN_is(*JOB->current, RS_AS))
	{
		if (!TRANS_type(TT_CAN_SQUARE, &ttyp))
			THROW("Syntax error in return type");
		event->type = ttyp.type;
	}*/
285

Benoît Minisini's avatar
Benoît Minisini committed
286 287
	TYPE_set_kind(&event->type, TK_EVENT);
	TYPE_set_flag(&event->type, TF_PUBLIC);
288

Benoît Minisini's avatar
Benoît Minisini committed
289
	return TRUE;
290 291 292 293 294
}


static bool header_property(TRANS_PROPERTY *prop)
{
295
	TRANS_DECL ptype = { 0 };
Benoît Minisini's avatar
Benoît Minisini committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
	PATTERN *look = JOB->current;
	bool is_static = FALSE;
	bool is_public = TRUE;

	CLEAR(prop);

	/* static */

	if (JOB->is_module)
	{
		is_static = TRUE;
	}
	else if (PATTERN_is(*look, RS_STATIC))
	{
		is_static = TRUE;
		look++;
	}

	/* public */

	if (PATTERN_is(*look, RS_PUBLIC) || PATTERN_is(*look, RS_PRIVATE))
	{
		is_public = PATTERN_is(*look, RS_PUBLIC);
		look++;
	}

	if (!PATTERN_is(*look, RS_PROPERTY))
		return FALSE;
	look++;
	JOB->current = look;

	if (!is_public)
		THROW("A property must be public");

	/* read-only property */

	if (PATTERN_is(*JOB->current, RS_READ))
	{
		prop->read = TRUE;
		JOB->current++;
	}
	else
		prop->read = FALSE;

	/* property name */

	if (!PATTERN_is_identifier(*JOB->current))
343
		THROW("Syntax error. Identifier expected for property name");
Benoît Minisini's avatar
Benoît Minisini committed
344 345 346

	prop->index = PATTERN_index(*JOB->current);
	JOB->current++;
Benoît Minisini's avatar
Benoît Minisini committed
347 348 349 350 351 352 353 354
	
	prop->nsynonymous = 0;
	
	while (TRANS_is(RS_COMMA))
	{
		if (prop->nsynonymous == 3)
			THROW("Too many property synonymous");
		if (!PATTERN_is_identifier(*JOB->current))
355
			THROW("Syntax error. Identifier expected for property synonymous");
Benoît Minisini's avatar
Benoît Minisini committed
356 357 358
		prop->synonymous[prop->nsynonymous++] = PATTERN_index(*JOB->current);
		JOB->current++;
	}
Benoît Minisini's avatar
Benoît Minisini committed
359 360

	if (!TRANS_type(TT_NOTHING, &ptype))
361
		THROW("Syntax error. Invalid property type");
Benoît Minisini's avatar
Benoît Minisini committed
362 363 364 365 366 367 368 369 370

	prop->type = ptype.type;
	prop->line = JOB->line;

	TYPE_set_kind(&prop->type, TK_PROPERTY);
	if (is_static)
		TYPE_set_flag(&prop->type, TF_STATIC);
	TYPE_set_flag(&prop->type, TF_PUBLIC);

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
	if (TRANS_is(RS_USE))
	{
		TRANS_DECL decl = ptype;
		
		TYPE_set_kind(&decl.type, TK_VARIABLE);
		if (is_static)
			TYPE_set_flag(&decl.type, TF_STATIC);

		if (!PATTERN_is_identifier(*JOB->current))
			THROW("Syntax error. Identifier expected for property variable");
		
		prop->use = PATTERN_index(*JOB->current);
		JOB->current++;
		
		decl.index = prop->use;
		CLASS_add_declaration(JOB->class, &decl);
	}
	
Benoît Minisini's avatar
Benoît Minisini committed
389 390 391 392 393 394 395 396 397
	if (PATTERN_is_string(*JOB->current))
	{
		prop->comment = PATTERN_index(*JOB->current);
		JOB->current++;
	}
	else
		prop->comment = NO_SYMBOL;

	return TRUE;
398 399
}

Benoît Minisini's avatar
Benoît Minisini committed
400 401
static bool header_extern(TRANS_EXTERN *trans)
{
Benoît Minisini's avatar
Benoît Minisini committed
402 403 404 405
	PATTERN *look = JOB->current;
	TRANS_DECL ttyp;
	int index;
	bool is_public;
406

Benoît Minisini's avatar
Benoît Minisini committed
407 408
	check_public_private(&look, &is_public);
	
Benoît Minisini's avatar
Benoît Minisini committed
409 410 411 412 413 414 415
	if (!PATTERN_is(*look, RS_EXTERN))
		return FALSE;
	look++;

	CLEAR(trans);

	JOB->current = look;
Benoît Minisini's avatar
Benoît Minisini committed
416
	analyze_function_desc((TRANS_FUNC *)trans, HF_NO_BYREF);
Benoît Minisini's avatar
Benoît Minisini committed
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458

	if (PATTERN_is(*JOB->current, RS_AS))
	{
		if (!TRANS_type(TT_NOTHING, &ttyp))
			THROW("Syntax error in return type");
		trans->type = ttyp.type;
	}

	if (TRANS_is(RS_IN))
	{
		if (!PATTERN_is_string(*JOB->current))
			THROW("Library name must be a string");

		index = PATTERN_index(*JOB->current);
		JOB->current++;
	}
	else
	{
		if (JOB->default_library == NO_SYMBOL)
			THROW(E_MISSING, "IN");

		index = JOB->default_library;
	}

	trans->library = index;

	if (TRANS_is(RS_EXEC))
	{
		if (!PATTERN_is_string(*JOB->current))
			THROW("Alias name must be a string");

		trans->alias = PATTERN_index(*JOB->current);
		JOB->current++;
	}
	else
		trans->alias = NO_SYMBOL;

	TYPE_set_kind(&trans->type, TK_EXTERN);
	TYPE_set_flag(&trans->type, TF_STATIC);
	if (is_public) TYPE_set_flag(&trans->type, TF_PUBLIC);

	return TRUE;
459 460 461 462
}

static bool header_class(TRANS_DECL *decl)
{
Benoît Minisini's avatar
Benoît Minisini committed
463 464
	if (!TRANS_is(RS_CLASS))
		return FALSE;
465

Benoît Minisini's avatar
Benoît Minisini committed
466 467
	if (!PATTERN_is_identifier(*JOB->current))
		THROW("Syntax error. CLASS needs an identifier");
468

Benoît Minisini's avatar
Benoît Minisini committed
469 470 471
	CLEAR(decl);
	decl->index = PATTERN_index(*JOB->current);
	JOB->current++;
472

Benoît Minisini's avatar
Benoît Minisini committed
473
	return TRUE;
474 475 476 477
}

static bool header_declaration(TRANS_DECL *decl)
{
Benoît Minisini's avatar
Benoît Minisini committed
478 479 480 481 482
	PATTERN *look = JOB->current;
	PATTERN *save;
	bool is_static = FALSE;
	bool is_public = FALSE;
	bool is_const = FALSE;
Benoît Minisini's avatar
Benoît Minisini committed
483
	bool no_warning = FALSE;
Benoît Minisini's avatar
Benoît Minisini committed
484 485 486 487 488 489 490 491 492 493

	/* static ! */

	if (JOB->is_module)
	{
		is_static = TRUE;
	}
	else if (PATTERN_is(*look, RS_STATIC))
	{
		is_static = TRUE;
Benoît Minisini's avatar
Benoît Minisini committed
494
		//has_static = TRUE;
Benoît Minisini's avatar
Benoît Minisini committed
495 496
		look++;
	}
497

Benoît Minisini's avatar
Benoît Minisini committed
498
	check_public_private(&look, &is_public);
499

Benoît Minisini's avatar
Benoît Minisini committed
500
	/* const ? */
501

Benoît Minisini's avatar
Benoît Minisini committed
502
	is_const = FALSE;
503

Benoît Minisini's avatar
Benoît Minisini committed
504 505
	if (PATTERN_is(*look, RS_CONST))
	{
Benoît Minisini's avatar
Benoît Minisini committed
506 507
		//if (has_static)
		//	THROW("Unexpected &1", "STATIC");
508

Benoît Minisini's avatar
Benoît Minisini committed
509 510 511
		is_const = TRUE;
		look++;
	}
512

Benoît Minisini's avatar
Benoît Minisini committed
513 514 515 516 517 518
	if (PATTERN_is(*look, RS_LBRA))
	{
		no_warning = TRUE;
		look++;
	}

Benoît Minisini's avatar
Benoît Minisini committed
519 520
	if (!PATTERN_is_identifier(*look))
		return FALSE;
521

Benoît Minisini's avatar
Benoît Minisini committed
522
	CLEAR(decl);
523

Benoît Minisini's avatar
Benoît Minisini committed
524 525
	decl->index = PATTERN_index(*look);
	look++;
526

Benoît Minisini's avatar
Benoît Minisini committed
527 528 529 530 531 532 533 534
	if (no_warning)
	{
		if (!PATTERN_is(*look, RS_RBRA))
			return FALSE;
		look++;
		decl->no_warning = TRUE;
	}

Benoît Minisini's avatar
Benoît Minisini committed
535 536
	save = JOB->current;
	JOB->current = look;
537

Benoît Minisini's avatar
Benoît Minisini committed
538 539 540 541 542
	if (!TRANS_type((!is_const ? TT_CAN_ARRAY | TT_CAN_EMBED : 0) | TT_CAN_NEW, decl))
	{
		JOB->current = save;
		return FALSE;
	}
543

Benoît Minisini's avatar
Benoît Minisini committed
544 545 546 547 548 549
	if (is_static) TYPE_set_flag(&decl->type, TF_STATIC);
	if (is_public) TYPE_set_flag(&decl->type, TF_PUBLIC);
	if (is_const)
		TYPE_set_kind(&decl->type, TK_CONST);
	else
		TYPE_set_kind(&decl->type, TK_VARIABLE);
550

Benoît Minisini's avatar
Benoît Minisini committed
551 552 553 554
	if (is_const)
	{
		if (!decl->init)
			THROW(E_SYNTAX_MISSING, "'='");
555

Benoît Minisini's avatar
Benoît Minisini committed
556
		JOB->current = decl->init;
557
		JOB->current = TRANS_get_constant_value(decl, JOB->current);
Benoît Minisini's avatar
Benoît Minisini committed
558
	}
559

Benoît Minisini's avatar
Benoît Minisini committed
560
	//JOB->current = look;
561

Benoît Minisini's avatar
Benoît Minisini committed
562
	return TRUE;
563 564 565
}


Benoît Minisini's avatar
Benoît Minisini committed
566 567
static bool header_enumeration(TRANS_DECL *decl)
{
Benoît Minisini's avatar
Benoît Minisini committed
568
	PATTERN *look = JOB->current;
Benoît Minisini's avatar
Benoît Minisini committed
569 570 571 572 573
	bool is_public;
	int value = 0;
	
	check_public_private(&look, &is_public);
	
Benoît Minisini's avatar
Benoît Minisini committed
574 575
	if (!PATTERN_is(*look, RS_ENUM))
		return FALSE;
Benoît Minisini's avatar
Benoît Minisini committed
576 577 578 579 580 581
	look++;

	JOB->current = look;
	
	for(;;)
	{
Benoît Minisini's avatar
Benoît Minisini committed
582 583
		TRANS_newline();

Benoît Minisini's avatar
Benoît Minisini committed
584
		if (!PATTERN_is_identifier(*JOB->current))
Benoît Minisini's avatar
Benoît Minisini committed
585
			THROW("Syntax error. Identifier expected");
Benoît Minisini's avatar
Benoît Minisini committed
586 587 588 589 590 591
		
		CLEAR(decl);

		decl->index = PATTERN_index(*JOB->current);
		JOB->current++;
	
Benoît Minisini's avatar
Benoît Minisini committed
592
		decl->type = TYPE_make_simple(T_INTEGER);
Benoît Minisini's avatar
Benoît Minisini committed
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607

		if (is_public) TYPE_set_flag(&decl->type, TF_PUBLIC);
		TYPE_set_kind(&decl->type, TK_CONST);

		if (TRANS_is(RS_EQUAL))
		{
			JOB->current = TRANS_get_constant_value(decl, JOB->current);
			value = decl->value + 1;
		}
		else
		{
			decl->value = value;
			value++;
		}
		
Benoît Minisini's avatar
Benoît Minisini committed
608
		CLASS_add_declaration(JOB->class, decl);
Benoît Minisini's avatar
Benoît Minisini committed
609 610 611 612 613

		if (TRANS_newline())
			break;

		if (!PATTERN_is(*JOB->current, RS_COMMA))
Benoît Minisini's avatar
Benoît Minisini committed
614
			THROW_UNEXPECTED(JOB->current);
Benoît Minisini's avatar
Benoît Minisini committed
615 616 617 618 619 620 621
		JOB->current++;
	}	
	
	return TRUE;
}


622 623
static bool header_function(TRANS_FUNC *func)
{
Benoît Minisini's avatar
Benoît Minisini committed
624 625 626 627 628 629 630 631 632 633 634 635 636
	static HEADER_SPECIAL spec[] =
	{
		{ "_init",      HS_PUBLIC + HS_STATIC + HS_PROCEDURE + HS_NOPARAM },
		{ "_exit",      HS_PUBLIC + HS_STATIC + HS_PROCEDURE + HS_NOPARAM},
		{ "_new",       HS_PUBLIC + HS_DYNAMIC + HS_PROCEDURE },
		{ "_free",      HS_PUBLIC + HS_DYNAMIC + HS_PROCEDURE + HS_NOPARAM },
		{ "_call",      HS_PUBLIC },
		{ "_get",       HS_PUBLIC + HS_FUNCTION },
		{ "_put",       HS_PUBLIC + HS_PROCEDURE + HS_PUT },
		{ "_next",      HS_PUBLIC + HS_NOPARAM },
		{ "_property",  HS_PUBLIC + HS_NOPARAM + HS_FUNCTION + HS_PROPERTY },
		{ "_unknown",   HS_PUBLIC + HS_UNKNOWN },
		{ "_compare",   HS_PUBLIC + HS_DYNAMIC + HS_FUNCTION + HS_COMPARE },
Benoît Minisini's avatar
Benoît Minisini committed
637
		{ "_attach",    HS_PUBLIC + HS_DYNAMIC + HS_PROCEDURE + HS_ATTACH },
Benoît Minisini's avatar
Benoît Minisini committed
638 639 640 641 642 643 644 645 646 647 648 649
		{ NULL, 0 }
	};

	PATTERN *look = JOB->current;
	PATTERN pat;
	TRANS_DECL ttyp;
	SYMBOL *sym;
	HEADER_SPECIAL *hsp;

	bool is_proc = FALSE;
	bool is_static = FALSE;
	bool is_public = FALSE;
Benoît Minisini's avatar
Benoît Minisini committed
650
	bool is_fast = FALSE;
Benoît Minisini's avatar
Benoît Minisini committed
651
	bool is_unsafe = FALSE;
Benoît Minisini's avatar
Benoît Minisini committed
652

Benoît Minisini's avatar
Benoît Minisini committed
653 654 655 656 657 658
	// fast ?
	
	if (PATTERN_is(*look, RS_FAST))
	{
		is_fast = TRUE;
		look++;
Benoît Minisini's avatar
Benoît Minisini committed
659 660 661 662 663 664
		
		if (PATTERN_is(*look, RS_UNSAFE))
		{
			is_unsafe = TRUE;
			look++;
		}
Benoît Minisini's avatar
Benoît Minisini committed
665 666 667
	}
	
	// static ?
Benoît Minisini's avatar
Benoît Minisini committed
668 669 670 671 672 673 674 675 676 677 678

	if (JOB->is_module)
	{
		is_static = TRUE;
	}
	else if (PATTERN_is(*look, RS_STATIC))
	{
		is_static = TRUE;
		look++;
	}

Benoît Minisini's avatar
Benoît Minisini committed
679
	// public ou static ?
Benoît Minisini's avatar
Benoît Minisini committed
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715

	is_public = JOB->is_module && JOB->public_module;

	if (PATTERN_is(*look, RS_PUBLIC))
	{
		is_public = TRUE;
		look++;
	}
	else if (PATTERN_is(*look, RS_PRIVATE))
	{
		is_public = FALSE;
		look++;
	}

	if (PATTERN_is(*look, RS_PROCEDURE) || PATTERN_is(*look, RS_SUB))
		is_proc = TRUE;
	else if (!PATTERN_is(*look, RS_FUNCTION))
		return FALSE;
	look++;

	//CLEAR(func);

	JOB->current = look;
	analyze_function_desc(func, HF_NORMAL);

	if (PATTERN_is(*JOB->current, RS_AS))
	{
		if (!TRANS_type(TT_NOTHING, &ttyp))
			THROW("Syntax error. Invalid return type");
		func->type = ttyp.type;
		is_proc = FALSE;
	}

	TYPE_set_kind(&func->type, TK_FUNCTION);
	if (is_static) TYPE_set_flag(&func->type, TF_STATIC);
	if (is_public) TYPE_set_flag(&func->type, TF_PUBLIC);
Benoît Minisini's avatar
Benoît Minisini committed
716
	
717
	func->fast = is_fast || JOB->class->all_fast;
718 719
	if (func->fast)
		JOB->class->has_fast = TRUE;
Benoît Minisini's avatar
Benoît Minisini committed
720 721
	
	func->unsafe = is_unsafe || JOB->class->all_unsafe;
Benoît Minisini's avatar
Benoît Minisini committed
722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778

	// Check special methods

	sym = TABLE_get_symbol(JOB->class->table, func->index);

	if (*sym->name == '_')
	{
		for (hsp = spec; hsp->name; hsp++)
		{
			if (sym->len != strlen(hsp->name))
				continue;
			if (strncmp(sym->name, hsp->name, sym->len))
				continue;

			if (hsp->flag == HS_ERROR)
				THROW("The special method &1 cannot be implemented", hsp->name);

			if ((hsp->flag & HS_PUBLIC) && !is_public)
				THROW("The special method &1 must be public", hsp->name);

			if ((hsp->flag & HS_STATIC) && !is_static)
				THROW("The special method &1 must be static", hsp->name);

			if ((hsp->flag & HS_DYNAMIC) && is_static)
				THROW("The special method &1 cannot be static", hsp->name);

			if ((hsp->flag & HS_PROCEDURE) && !is_proc)
				THROW("The special method &1 cannot be a function", hsp->name);

			if ((hsp->flag & HS_FUNCTION) && is_proc)
				THROW("The special method &1 must be a function", hsp->name);

			if ((hsp->flag & HS_NOPARAM) && func->nparam > 0)
				THROW("The special method &1 takes no arguments", hsp->name);

			if (hsp->flag & HS_PUT)
			{
				if (func->nparam < 1)
					THROW("The special method &1 must take at least one argument", hsp->name);
			}

			if (hsp->flag & HS_UNKNOWN)
			{
				if (func->nparam > 0 || !func->vararg)
					THROW("The special method &1 must take a variable number of arguments only", hsp->name);
			}

			if (hsp->flag & HS_PROPERTY)
			{
				if (TYPE_get_id(func->type) != T_BOOLEAN)
					THROW("The special method &1 must return a boolean", hsp->name);
			}

			if (hsp->flag & HS_COMPARE)
			{
				if (func->type.t.id != T_INTEGER)
					THROW("The special method must return an integer");
779
				if (func->nparam != 1)
Benoît Minisini's avatar
Benoît Minisini committed
780 781
					THROW("The special method must take exactly one argument");
			}
Benoît Minisini's avatar
Benoît Minisini committed
782 783 784 785
			
			if (hsp->flag & HS_ATTACH)
			{
				if (func->nparam != 2)
Benoît Minisini's avatar
Benoît Minisini committed
786
					THROW("The special method must take exactly two arguments");
Benoît Minisini's avatar
Benoît Minisini committed
787
				if (func->param[0].type.t.id != T_OBJECT || func->param[1].type.t.id != T_STRING)
Benoît Minisini's avatar
Benoît Minisini committed
788
					THROW("The special method signature is incorrect");
Benoît Minisini's avatar
Benoît Minisini committed
789
			}
790

Benoît Minisini's avatar
Benoît Minisini committed
791 792 793
			break;
		}
	}
794 795


Benoît Minisini's avatar
Benoît Minisini committed
796
	// We ignore function body
797

Benoît Minisini's avatar
Benoît Minisini committed
798 799
	if (!PATTERN_is_newline(*(JOB->current)))
		THROW("Syntax error at function declaration");
800

Benoît Minisini's avatar
Benoît Minisini committed
801 802
	func->line = PATTERN_index(*(JOB->current)) + 1;
	func->start = JOB->current + 1;
803

Benoît Minisini's avatar
Benoît Minisini committed
804
	look = JOB->current;
Benoît Minisini's avatar
Benoît Minisini committed
805 806 807
	for(;;)
	{
		pat = *look;
808

Benoît Minisini's avatar
Benoît Minisini committed
809
		if (PATTERN_is_newline(pat))
Benoît Minisini's avatar
Benoît Minisini committed
810 811
		{
			JOB->line = PATTERN_index(pat) + 1;
Benoît Minisini's avatar
Benoît Minisini committed
812
			pat = look[1];
Benoît Minisini's avatar
Benoît Minisini committed
813
			
Benoît Minisini's avatar
Benoît Minisini committed
814 815 816 817 818 819 820 821 822 823 824 825
			if (PATTERN_is(pat, RS_END))
			{
				if (PATTERN_is_newline(look[2]))
				{
					look += 2;
					break;
				}
				if (TRANS_is_end_function(is_proc, &look[2]))
				{
					look += 3;
					break;
				}
Benoît Minisini's avatar
Benoît Minisini committed
826 827
				else
				{
Benoît Minisini's avatar
Benoît Minisini committed
828
					if (is_proc && PATTERN_is(look[2], RS_FUNCTION))
Benoît Minisini's avatar
Benoît Minisini committed
829
						THROW(E_EXPECTED, "END SUB");
Benoît Minisini's avatar
Benoît Minisini committed
830
					else if (!is_proc && PATTERN_is(look[2], RS_SUB))
Benoît Minisini's avatar
Benoît Minisini committed
831
						THROW(E_EXPECTED, "END FUNCTION");
Benoît Minisini's avatar
Benoît Minisini committed
832
				}
Benoît Minisini's avatar
Benoît Minisini committed
833
			}
Benoît Minisini's avatar
Benoît Minisini committed
834
			else if (UNLIKELY(PATTERN_is_end(pat))) // || PATTERN_is_command(pat)))
Benoît Minisini's avatar
Benoît Minisini committed
835
				THROW(E_MISSING, "END");
Benoît Minisini's avatar
Benoît Minisini committed
836
		}
837

Benoît Minisini's avatar
Benoît Minisini committed
838 839
		look++;
	}
840

Benoît Minisini's avatar
Benoît Minisini committed
841
	JOB->current = look;
Benoît Minisini's avatar
Benoît Minisini committed
842
	return TRUE;
843 844 845 846 847
}


static bool header_inherits(void)
{
Benoît Minisini's avatar
Benoît Minisini committed
848
	int index;
849

Benoît Minisini's avatar
Benoît Minisini committed
850 851
	if (!PATTERN_is(*JOB->current, RS_INHERITS))
		return FALSE;
852

Benoît Minisini's avatar
Benoît Minisini committed
853 854 855 856 857 858
	/*{
		if (!(PATTERN_is(JOB->current[0], RS_CLASS)
					&& PATTERN_is(JOB->current[1], RS_INHERITS)))
			return FALSE;
		JOB->current++;
	}*/
859

Benoît Minisini's avatar
Benoît Minisini committed
860
	JOB->current++;
861

Benoît Minisini's avatar
Benoît Minisini committed
862 863
	if (!PATTERN_is_class(*JOB->current))
		THROW("Syntax error. INHERITS needs a class name");
864

Benoît Minisini's avatar
Benoît Minisini committed
865 866
	if (JOB->class->parent != NO_SYMBOL)
		THROW("Cannot inherit twice");
Benoît Minisini's avatar
Benoît Minisini committed
867
	
Benoît Minisini's avatar
Benoît Minisini committed
868
	index = PATTERN_index(*JOB->current);
Benoît Minisini's avatar
Benoît Minisini committed
869 870 871
	
	if (strcasecmp(TABLE_get_symbol_name(JOB->class->table, index), JOB->class->name) == 0)
		THROW("Cannot inherit itself");
872

Benoît Minisini's avatar
Benoît Minisini committed
873 874
	JOB->class->parent = CLASS_add_class(JOB->class, index);
	/*printf("JOB->class->parent = %d\n", JOB->class->parent);*/
875

Benoît Minisini's avatar
Benoît Minisini committed
876 877
	JOB->current++;
	return TRUE;
878 879 880 881 882
}


static bool header_option(void)
{
Benoît Minisini's avatar
Benoît Minisini committed
883
	if (TRANS_is(RS_EXPORT))
Benoît Minisini's avatar
Benoît Minisini committed
884 885
	{
		JOB->class->exported = TRUE;
886

Benoît Minisini's avatar
Benoît Minisini committed
887
		if (TRANS_is(RS_OPTIONAL))
Benoît Minisini's avatar
Benoît Minisini committed
888
			JOB->class->optional = TRUE;
889

Benoît Minisini's avatar
Benoît Minisini committed
890 891
		return TRUE;
	}
892

Benoît Minisini's avatar
Benoît Minisini committed
893
	if (TRANS_is(RS_CREATE))
Benoît Minisini's avatar
Benoît Minisini committed
894 895
	{
		if (PATTERN_is_newline(JOB->current[0]) || PATTERN_is(JOB->current[0], RS_STATIC))
896
		{
Benoît Minisini's avatar
Benoît Minisini committed
897
			JOB->class->autocreate = TRUE;
Benoît Minisini's avatar
Benoît Minisini committed
898
			TRANS_ignore(RS_STATIC);
Benoît Minisini's avatar
Benoît Minisini committed
899
			return TRUE;
900
		}
Benoît Minisini's avatar
Benoît Minisini committed
901
		else if (TRANS_is(RS_PRIVATE))
902
		{
Benoît Minisini's avatar
Benoît Minisini committed
903 904
			JOB->class->nocreate = TRUE;
			return TRUE;
905
		}
Benoît Minisini's avatar
Benoît Minisini committed
906
	}
Emil Lenngren's avatar
Emil Lenngren committed
907
	
Benoît Minisini's avatar
Benoît Minisini committed
908
	if (TRANS_is(RS_FAST))
Emil Lenngren's avatar
Emil Lenngren committed
909
	{
910 911
		JOB->class->all_fast = TRUE;
		JOB->class->has_fast = TRUE;
Benoît Minisini's avatar
Benoît Minisini committed
912 913 914 915
		
		if (TRANS_is(RS_UNSAFE))
			JOB->class->all_unsafe = TRUE;
		
Emil Lenngren's avatar
Emil Lenngren committed
916 917
		return TRUE;
	}
918

Benoît Minisini's avatar
Benoît Minisini committed
919
	return FALSE;
920 921
}

Benoît Minisini's avatar
Benoît Minisini committed
922

923 924
static bool header_library(void)
{
Benoît Minisini's avatar
Benoît Minisini committed
925 926
	if (!TRANS_is(RS_LIBRARY))
		return FALSE;
927

Benoît Minisini's avatar
Benoît Minisini committed
928
	if (!PATTERN_is_string(*JOB->current))
Benoît Minisini's avatar
Benoît Minisini committed
929
		THROW("Extern library name must be a string");
930

Benoît Minisini's avatar
Benoît Minisini committed
931 932 933
	JOB->default_library = PATTERN_index(*JOB->current);
	JOB->current++;
	return TRUE;
934 935 936
}


Benoît Minisini's avatar
Benoît Minisini committed
937 938
static bool header_structure(void)
{
Benoît Minisini's avatar
Benoît Minisini committed
939
	PATTERN *look = JOB->current;
Benoît Minisini's avatar
Benoît Minisini committed
940 941 942 943 944
	bool is_public;
	CLASS_STRUCT *structure;
	VARIABLE *field;
	TRANS_DECL decl;
	int nfield;
Benoît Minisini's avatar
Benoît Minisini committed
945
	int index;
Benoît Minisini's avatar
Benoît Minisini committed
946 947 948

	check_public_private(&look, &is_public);
	
Benoît Minisini's avatar
Benoît Minisini committed
949 950 951
	if (!PATTERN_is(*look, RS_STRUCT))
		return FALSE;
	look++;
Benoît Minisini's avatar
Benoît Minisini committed
952 953 954 955 956
	JOB->current = look;
	
	if (!is_public)
		THROW("Structures must be public");
	
Benoît Minisini's avatar
Benoît Minisini committed
957 958
	if (!PATTERN_is_identifier(*JOB->current))
		THROW("Syntax error. STRUCT needs an identifier");
Benoît Minisini's avatar
Benoît Minisini committed
959 960 961 962 963

	structure = ARRAY_add_void(&JOB->class->structure);
	ARRAY_create(&structure->field);
	nfield = 0;
	
Benoît Minisini's avatar
Benoît Minisini committed
964 965
	structure->index = PATTERN_index(*JOB->current);
	index = CLASS_add_class_exported(JOB->class, structure->index);
Benoît Minisini's avatar
Benoît Minisini committed
966
	JOB->class->class[index].structure = TRUE;
Benoît Minisini's avatar
Benoît Minisini committed
967
	//fprintf(stderr, "Set structure flag to %s\n", TABLE_get_symbol_name(JOB->class->table, structure->index));
Benoît Minisini's avatar
Benoît Minisini committed
968 969

//TABLE_copy_symbol_with_prefix(JOB->class->table, structure->index, '.', NULL, &structure->index);
Benoît Minisini's avatar
Benoît Minisini committed
970 971 972 973 974 975 976 977

	JOB->current++;
	TRANS_want_newline();
	
	for(;;)
	{
		do
		{
Benoît Minisini's avatar
Benoît Minisini committed
978 979
			if (PATTERN_is_end(*JOB->current)) // || PATTERN_is_command(*JOB->current))
				THROW ("Missing END STRUCT");
Benoît Minisini's avatar
Benoît Minisini committed
980 981 982 983 984
		}
		while (TRANS_newline());
		
		if (PATTERN_is(*JOB->current, RS_END) && PATTERN_is(JOB->current[1], RS_STRUCT))
		{
Benoît Minisini's avatar
Benoît Minisini committed
985 986 987
			if (nfield == 0)
				THROW ("Syntax error. A structure must have one field at least.");
				
Benoît Minisini's avatar
Benoît Minisini committed
988
			JOB->current += 2;
Benoît Minisini's avatar
Benoît Minisini committed
989
			
Benoît Minisini's avatar
Benoît Minisini committed
990
			TRANS_want_newline();
Benoît Minisini's avatar
Benoît Minisini committed
991
			break;
Benoît Minisini's avatar
Benoît Minisini committed
992 993
		}
		
Benoît Minisini's avatar
Benoît Minisini committed
994 995
		if (!PATTERN_is_identifier(*JOB->current))
			THROW("Syntax error. The &1 field is not a valid identifier", TRANS_get_num_desc(nfield + 1));
Benoît Minisini's avatar
Benoît Minisini committed
996 997 998 999 1000

		field = ARRAY_add(&structure->field);
		field->index = PATTERN_index(*JOB->current); 
		
		
Benoît Minisini's avatar
Benoît Minisini committed
1001 1002
		JOB->current++;
		
Benoît Minisini's avatar
Benoît Minisini committed
1003
		CLEAR(&decl);
Benoît Minisini's avatar
Benoît Minisini committed
1004 1005
		if (!TRANS_type(TT_CAN_ARRAY | TT_CAN_EMBED, &decl))
			THROW("Syntax error. Invalid type description of &1 field", TRANS_get_num_desc(nfield + 1));
Benoît Minisini's avatar
Benoît Minisini committed
1006 1007

		TRANS_want_newline();
Benoît Minisini's avatar
Benoît Minisini committed
1008
		
Benoît Minisini's avatar
Benoît Minisini committed
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
		field->type = decl.type;
		
		nfield++;
	}
	
	structure->nfield = nfield;
	
	return TRUE;
}

Benoît Minisini's avatar
Benoît Minisini committed
1019 1020 1021 1022 1023 1024 1025
static bool header_use(void)
{
	if (!TRANS_is(RS_USE))
		return FALSE;

	CLASS_begin_init_function(JOB->class, FUNC_INIT_STATIC);

Benoît Minisini's avatar
Benoît Minisini committed
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
	for(;;)
	{
		if (!PATTERN_is_string(*JOB->current))
			THROW("Component name must be a string");

		TRANS_string(*JOB->current);
		TRANS_subr(TS_SUBR_USE, 1);
		CODE_drop();

		JOB->current++;

		if (!TRANS_is(RS_COMMA))
			break;
	}
Benoît Minisini's avatar
Benoît Minisini committed
1040 1041

	if (!PATTERN_is_newline(*JOB->current))
Benoît Minisini's avatar
Benoît Minisini committed
1042
		THROW(E_SYNTAX);
Benoît Minisini's avatar
Benoît Minisini committed
1043 1044 1045 1046 1047

	return TRUE;
}


Benoît Minisini's avatar
Benoît Minisini committed
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
static void check_class_header()
{
	while (TRUE) //(JOB->current < JOB->end)
	{
		if (PATTERN_is_end(*JOB->current))
			break;

		if (TRANS_newline())
			continue;

		if (header_option())
			continue;
		
		if (header_inherits())
			continue;

		break;
	}
}

Benoît Minisini's avatar
Benoît Minisini committed
1068
void HEADER_do(void)
1069
{
Benoît Minisini's avatar
Benoît Minisini committed
1070 1071 1072 1073 1074 1075 1076
	union {
		TRANS_DECL decl;
		TRANS_FUNC func;
		TRANS_EVENT event;
		TRANS_EXTERN ext;
		TRANS_PROPERTY prop;
		} trans;
1077

Benoît Minisini's avatar
Benoît Minisini committed
1078
	TRANS_reset();
1079

Benoît Minisini's avatar
Benoît Minisini committed
1080
	header_module_type();
Benoît Minisini's avatar
Benoît Minisini committed
1081 1082 1083
	
	if (JOB->line == 1)
		check_class_header();
1084

Benoît Minisini's avatar
Benoît Minisini committed
1085 1086 1087 1088
	while (TRUE) //JOB->current < JOB->end)
	{
		if (PATTERN_is_end(*JOB->current))
			break;
Benoît Minisini's avatar
Benoît Minisini committed
1089
		
Benoît Minisini's avatar
Benoît Minisini committed
1090
		if (TRANS_newline())
Benoît Minisini's avatar
Benoît Minisini committed
1091 1092 1093 1094
		{
			if (JOB->line == 1)
				check_class_header();
			
Benoît Minisini's avatar
Benoît Minisini committed
1095
			continue;
Benoît Minisini's avatar
Benoît Minisini committed
1096
		}
1097

Benoît Minisini's avatar
Benoît Minisini committed
1098 1099 1100
		if (header_function(&trans.func))
		{
			CLASS_add_function(JOB->class, &trans.func);
Benoît Minisini's avatar
Benoît Minisini committed
1101
			continue;
Benoît Minisini's avatar
Benoît Minisini committed
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
		}

		if (header_event(&trans.event))
		{
			CLASS_add_event(JOB->class, &trans.event);
			continue;
		}

		if (header_property(&trans.prop))
		{
			CLASS_add_property(JOB->class, &trans.prop);
			continue;
		}

		if (header_extern(&trans.ext))
		{
			CLASS_add_extern(JOB->class, &trans.ext);
			continue;
		}
Benoît Minisini's avatar
Benoît Minisini committed
1121
		
Benoît Minisini's avatar
Benoît Minisini committed
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
		if (header_enumeration(&trans.decl))
			continue;
		
		if (header_declaration(&trans.decl))
		{
			CLASS_add_declaration(JOB->class, &trans.decl);
			continue;
		}
		
		if (header_structure())
			continue;

		if (header_class(&trans.decl))
		{
			CLASS_add_class_exported(JOB->class, trans.decl.index);
			continue;
		}

		if (header_inherits())
			continue;

		if (header_library())
			continue;
1145

Benoît Minisini's avatar
Benoît Minisini committed
1146 1147 1148
		if (header_use())
			continue;

Benoît Minisini's avatar
Benoît Minisini committed
1149
		/*if (PATTERN_is_command(*JOB->current))
Benoît Minisini's avatar
Benoît Minisini committed
1150 1151 1152
		{
			JOB->current++;
			continue;
Benoît Minisini's avatar
Benoît Minisini committed
1153
		}*/
Benoît Minisini's avatar
Benoît Minisini committed
1154

Benoît Minisini's avatar
Benoît Minisini committed
1155 1156
		THROW_UNEXPECTED(JOB->current);
	}
1157

Benoît Minisini's avatar
Benoît Minisini committed
1158 1159 1160
	// Sort class declaration to avoid alignment problems.
	// This should be useless now, as it is done again by the interpreter
	// when loading the class.
1161

Benoît Minisini's avatar
Benoît Minisini committed
1162
	CLASS_sort_declaration(JOB->class);
1163

Benoît Minisini's avatar
Benoît Minisini committed
1164 1165
	if (JOB->verbose)
		CLASS_dump();
1166
}