00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028
00029 #include <stdio.h>
00030 #include "ucstmt.h"
00031 #include "ucexpr.h"
00032 #include "ucsym.h"
00033 #include "opcodes.h"
00034 #include "utils.h"
00035 #include "ucfun.h"
00036
00037 using std::vector;
00038 using std::string;
00039
00040 int Uc_converse2_statement::nest = 0;
00041
00042
00043
00044
00045
00046 Uc_block_statement::~Uc_block_statement
00047 (
00048 )
00049 {
00050
00051 for (std::vector<Uc_statement *>::const_iterator it = statements.begin();
00052 it != statements.end(); it++)
00053 delete (*it);
00054 }
00055
00056
00057
00058
00059
00060 void Uc_block_statement::gen
00061 (
00062 vector<char>& out,
00063 Uc_function *fun
00064 )
00065 {
00066 for (std::vector<Uc_statement *>::const_iterator it = statements.begin();
00067 it != statements.end(); it++)
00068 {
00069 Uc_statement *stmt = *it;
00070 stmt->gen(out, fun);
00071 }
00072 }
00073
00074
00075
00076
00077
00078
00079 Uc_assignment_statement::~Uc_assignment_statement
00080 (
00081 )
00082 {
00083 delete target;
00084 delete value;
00085 }
00086
00087
00088
00089
00090
00091
00092 void Uc_assignment_statement::gen
00093 (
00094 vector<char>& out,
00095 Uc_function *
00096 )
00097 {
00098 value->gen_value(out);
00099 target->gen_assign(out);
00100 }
00101
00102
00103
00104
00105
00106 void Uc_if_statement::gen
00107 (
00108 vector<char>& out,
00109 Uc_function *fun
00110 )
00111 {
00112
00113 int jne_offset = expr->gen_jmp_if_false(out, 0);
00114 if (if_stmt)
00115 if_stmt->gen(out, fun);
00116 int jmp_past_else_offset = -1;
00117 if (else_stmt)
00118 {
00119 out.push_back((char) UC_JMP);
00120 jmp_past_else_offset = out.size();
00121 Write2(out, 0);
00122 }
00123 int if_end = out.size();
00124
00125 Write2(out, jne_offset, if_end - (jne_offset + 2));
00126 if (else_stmt)
00127 {
00128 else_stmt->gen(out, fun);
00129 int else_end = out.size();
00130 Write2(out, jmp_past_else_offset,
00131 else_end - (jmp_past_else_offset + 2));
00132 }
00133 }
00134
00135
00136
00137
00138
00139 Uc_if_statement::~Uc_if_statement
00140 (
00141 )
00142 {
00143 delete expr;
00144 delete if_stmt;
00145 delete else_stmt;
00146 }
00147
00148
00149
00150
00151
00152 Uc_while_statement::~Uc_while_statement
00153 (
00154 )
00155 {
00156 delete expr;
00157 delete stmt;
00158 }
00159
00160
00161
00162
00163
00164 void Uc_while_statement::gen
00165 (
00166 vector<char>& out,
00167 Uc_function *fun
00168 )
00169 {
00170 int top = out.size();
00171 expr->gen_value(out);
00172 vector<char> stmt_code;
00173 stmt_code.reserve(4000);
00174 fun->start_breakable(this);
00175 if (stmt) {
00176 fun->adjust_reloffset(out.size() + 3);
00177 stmt->gen(stmt_code, fun);
00178 fun->adjust_reloffset(-out.size() - 3);
00179 }
00180 int stmtlen = stmt_code.size();
00181
00182
00183 long dist = stmtlen + (out.size() - top) + 3 + 3;
00184
00185 stmt_code.push_back((char) UC_JMP);
00186 Write2(stmt_code, -dist);
00187 stmtlen = stmt_code.size();
00188 fun->end_breakable(this, stmt_code);
00189 out.push_back((char) UC_JNE);
00190 Write2(out, stmtlen);
00191
00192
00193 out.insert(out.end(), stmt_code.begin(), stmt_code.end());
00194 }
00195
00196
00197
00198
00199
00200 Uc_arrayloop_statement::~Uc_arrayloop_statement
00201 (
00202 )
00203 {
00204 delete stmt;
00205 }
00206
00207
00208
00209
00210
00211 void Uc_arrayloop_statement::finish
00212 (
00213 Uc_function *fun
00214 )
00215 {
00216 char buf[100];
00217 if (!index)
00218 {
00219 sprintf(buf, "_%s_index", array->get_name());
00220 index = fun->add_symbol(buf);
00221 }
00222 if (!array_size);
00223 {
00224 sprintf(buf, "_%s_size", array->get_name());
00225 array_size = fun->add_symbol(buf);
00226 }
00227 }
00228
00229
00230
00231
00232
00233 void Uc_arrayloop_statement::gen
00234 (
00235 vector<char>& out,
00236 Uc_function *fun
00237 )
00238 {
00239 if (!stmt)
00240 return;
00241 out.push_back((char) UC_LOOP);
00242 int top = out.size();
00243 out.push_back((char) UC_LOOPTOP);
00244 Write2(out, index->get_offset());
00245 Write2(out, array_size->get_offset());
00246 Write2(out, var->get_offset());
00247 Write2(out, array->get_offset());
00248
00249 int testlen = out.size() + 2 - top;
00250 vector<char> stmt_code;
00251 stmt_code.reserve(4000);
00252 fun->start_breakable(this);
00253 fun->adjust_reloffset(out.size() + 2);
00254 stmt->gen(stmt_code, fun);
00255 fun->adjust_reloffset(-out.size() - 2);
00256
00257 int dist = testlen + stmt_code.size() + 3;
00258 stmt_code.push_back((char) UC_JMP);
00259 Write2(stmt_code, -dist);
00260 int stmtlen = stmt_code.size();
00261 Write2(out, stmtlen);
00262 fun->end_breakable(this, stmt_code);
00263
00264 out.insert(out.end(), stmt_code.begin(), stmt_code.end());
00265 }
00266
00267
00268
00269
00270
00271 Uc_return_statement::~Uc_return_statement
00272 (
00273 )
00274 {
00275 delete expr;
00276 }
00277
00278
00279
00280
00281
00282 void Uc_return_statement::gen
00283 (
00284 vector<char>& out,
00285 Uc_function *fun
00286 )
00287 {
00288 if (expr)
00289 {
00290 expr->gen_value(out);
00291 out.push_back((char) UC_SETR);
00292 out.push_back((char) UC_RTS);
00293 }
00294 else
00295 out.push_back((char) UC_RET);
00296 }
00297
00298
00299
00300
00301
00302
00303 void Uc_break_statement::gen
00304 (
00305 vector<char>& out,
00306 Uc_function *fun
00307 )
00308 {
00309
00310 fun->add_break(out.size());
00311 out.push_back((char) UC_JMP);
00312 Write2(out, 0);
00313 }
00314
00315
00316 void Uc_label_statement::gen
00317 (
00318 vector<char>& out,
00319 Uc_function *fun
00320 )
00321 {
00322
00323
00324 label->set_offset(out.size() + fun->get_reloffset());
00325
00326
00327 }
00328
00329
00330 void Uc_goto_statement::gen
00331 (
00332 vector<char>& out,
00333 Uc_function *fun
00334 )
00335 {
00336 Uc_label *l = fun->search_label(label);
00337 if (l) {
00338
00339
00340 l->add_reference(out.size() + fun->get_reloffset());
00341 out.push_back((char) UC_JMP);
00342 Write2(out, 0);
00343 } else {
00344 char buf[255];
00345 snprintf(buf, 255, "Undeclared label: '%s'", label);
00346 error(buf);
00347 }
00348 }
00349
00350
00351
00352
00353
00354 Uc_converse_statement::~Uc_converse_statement
00355 (
00356 )
00357 {
00358 delete stmt;
00359 }
00360
00361
00362
00363
00364
00365 void Uc_converse_statement::gen
00366 (
00367 vector<char>& out,
00368 Uc_function *fun
00369 )
00370 {
00371 long top = out.size();
00372 vector<char> stmt_code;
00373 fun->start_breakable(this);
00374 if (stmt) {
00375 fun->adjust_reloffset(out.size() + 3);
00376 stmt->gen(stmt_code, fun);
00377 fun->adjust_reloffset(-out.size() - 3);
00378 }
00379 int stmtlen = stmt_code.size();
00380
00381
00382 long dist = stmtlen + 3 + 3;
00383 stmt_code.push_back((char) UC_JMP);
00384 Write2(stmt_code, -dist);
00385 stmtlen = stmt_code.size();
00386 fun->end_breakable(this, stmt_code);
00387 out.push_back((char) UC_CONVERSE);
00388 Write2(out, stmtlen);
00389
00390 out.insert(out.end(), stmt_code.begin(), stmt_code.end());
00391 out.push_back((char) UC_CONVERSELOC);
00392 }
00393
00394
00395
00396
00397 static void Call_intrinsic
00398 (
00399 vector<char>& out,
00400 Uc_function *fun,
00401 Uc_intrinsic_symbol *intr,
00402 Uc_expression *parm0 = 0
00403 )
00404 {
00405
00406 Uc_array_expression *parms = new Uc_array_expression;
00407 if (parm0)
00408 parms->add(parm0);
00409 Uc_call_expression *fcall = new Uc_call_expression(intr, parms, fun);
00410 Uc_call_statement fstmt(fcall);
00411 fstmt.gen(out, fun);
00412 parms->clear();
00413 }
00414
00415
00416
00417
00418
00419 void Uc_converse_case_statement::gen
00420 (
00421 vector<char>& out,
00422
00423 Uc_function *fun
00424 )
00425 {
00426 out.push_back((char) UC_PUSHS);
00427 Write2(out, string_offset);
00428 out.push_back((char) UC_CMPS);
00429 Write2(out, 1);
00430 int to_top_index = out.size();
00431 Write2(out, 0);
00432 if (remove)
00433 {
00434 Uc_string_expression str(string_offset);
00435 Call_intrinsic(out, fun,
00436 Uc_function::get_remove_answer(), &str);
00437 }
00438 if (statements)
00439 statements->gen(out, fun);
00440
00441
00442
00443 long dist = out.size() + 3 + 3;
00444
00445 out.push_back((char) UC_JMP);
00446 Write2(out, -dist);
00447
00448 Write2(out, to_top_index, out.size() - (to_top_index + 2));
00449 }
00450
00451
00452
00453
00454
00455 Uc_converse2_statement::~Uc_converse2_statement
00456 (
00457 )
00458 {
00459 delete answers;
00460 delete cases;
00461 }
00462
00463
00464
00465
00466
00467 void Uc_converse2_statement::gen
00468 (
00469 vector<char>& out,
00470 Uc_function *fun
00471 )
00472 {
00473 if (nest++ > 0)
00474
00475 Call_intrinsic(out, fun, Uc_function::get_push_answers());
00476 if (answers)
00477 Call_intrinsic(out, fun,
00478 Uc_function::get_add_answer(), answers);
00479 vector<char> stmt_code;
00480 fun->start_breakable(this);
00481 if (cases)
00482 {
00483 fun->adjust_reloffset(out.size() + 3);
00484 cases->gen(stmt_code, fun);
00485 fun->adjust_reloffset(-out.size() - 3);
00486 }
00487 int stmtlen = stmt_code.size();
00488
00489
00490 long dist = stmtlen + 3 + 3;
00491 stmt_code.push_back((char) UC_JMP);
00492 Write2(stmt_code, -dist);
00493 stmtlen = stmt_code.size();
00494 fun->end_breakable(this, stmt_code);
00495 out.push_back((char) UC_CONVERSE);
00496 Write2(out, stmtlen);
00497
00498 out.insert(out.end(), stmt_code.begin(), stmt_code.end());
00499 out.push_back((char) UC_CONVERSELOC);
00500 if (--nest > 0)
00501
00502 Call_intrinsic(out, fun, Uc_function::get_pop_answers());
00503 }
00504
00505
00506
00507
00508
00509 void Uc_message_statement::gen
00510 (
00511 vector<char>& out,
00512 Uc_function *fun
00513 )
00514 {
00515 if (!msgs)
00516 return;
00517 const std::vector<Uc_expression*>& exprs = msgs->get_exprs();
00518 for (std::vector<Uc_expression*>::const_iterator it = exprs.begin();
00519 it != exprs.end(); ++it)
00520 {
00521 Uc_expression *msg = *it;
00522
00523 int offset = msg->get_string_offset();
00524 if (offset >= 0)
00525 {
00526 out.push_back((char) UC_ADDSI);
00527 Write2(out, offset);
00528 }
00529 else
00530 {
00531 Uc_var_symbol *var = msg->need_var(out, fun);
00532 if (var)
00533 {
00534 out.push_back((char) UC_ADDSV);
00535 Write2(out, var->get_offset());
00536 }
00537 }
00538 }
00539 }
00540
00541
00542
00543
00544
00545 void Uc_say_statement::gen
00546 (
00547 vector<char>& out,
00548 Uc_function *fun
00549 )
00550 {
00551
00552 Uc_message_statement::gen(out, fun);
00553 out.push_back((char) UC_SAY);
00554 }
00555
00556
00557
00558
00559
00560 Uc_call_statement::Uc_call_statement
00561 (
00562 Uc_call_expression *f
00563 ) : function_call(f)
00564 {
00565 if (function_call)
00566 function_call->set_no_return();
00567 }
00568
00569
00570
00571
00572
00573 Uc_call_statement::~Uc_call_statement
00574 (
00575 )
00576 {
00577 delete function_call;
00578 }
00579
00580
00581
00582
00583
00584 void Uc_call_statement::gen
00585 (
00586 vector<char>& out,
00587 Uc_function *fun
00588 )
00589 {
00590 function_call->gen_value(out);
00591 }