Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Интерпретатор / _sources / MyLanguage / PolizInterpreter
.cpp#include <cmath>
#include <iostream>
#include <queue>
#include <vector>
#include "PolizInterpreter.hpp"
#include "Externs.hpp"
#include "Errors.hpp"
#include "TokenParser.hpp"
namespace Parser_impl {
long double PolizInterpreter::getValue(LookupTable<Variable>& local)
{
PolizInstruction& in = exec_stack.top();
exec_stack.pop();
if (in.inst_type == TLiteral){
return in.value;
} else if (in.inst_type == TVariable) {
if (in.local)
return local.get(in.val).value;
else
return progr->global.get(in.val).value;
} else
throw RuntimeException("Stack error");
return 0.0;
}
ElementTypes PolizInterpreter::getType(LookupTable<Variable>& local)
{
PolizInstruction in = exec_stack.top();
if (in.inst_type == TLiteral){
return ElementTypes(in.val);
} else if (in.inst_type == TVariable) {
if (in.local)
return local.get(in.val).type;
else
return progr->global.get(in.val).type;
} else
throw RuntimeException("Stack error");
return VOID;
}
void PolizInterpreter::setValue(LookupTable<Variable>& local, long double v)
{
PolizInstruction& in = exec_stack.top();
exec_stack.pop();
if (in.inst_type == TVariable) {
if (in.local){
Variable& var = local.get(in.val);
var.value = (var.type == INT) ? ( (long long)v ):(v);
} else {
Variable& var = progr->global.get(in.val);
var.value = (var.type == INT) ? ( (long long)v ):(v);
}
} else
throw RuntimeException("Stack error");
}
std::string PolizInterpreter::getString()
{
PolizInstruction& in = exec_stack.top();
exec_stack.pop();
if (in.inst_type == TStrLit) {
return in.str;
} else
throw RuntimeException("Stack error");
}
void PolizInterpreter::invoke(int f)
{
unsigned cursor = 0;
Function& func = progr->functions.get(f);
LookupTable<Variable> local = func.local;
if (f != progr->main && func.args_count > 0) {
// Filling arguments of function f
if (exec_stack.size()< unsigned(func.args_count))
throw RuntimeException("Stack error");
for (int i = func.args_count-1; i>=0; --i){
Variable& v = local.get(i);
long double d =getValue(local);
v.value = (v.type == INT)? ((long long)d):d;
}
}
bool was_return = false;
while(cursor != func.code.size()){
PolizInstruction instr = func.code[cursor];
switch ( instr.inst_type ) {
case TVariable:
case TStrLit:
case TLiteral:
exec_stack.push(instr);
break;
case TFunction:{
Function& f = progr->functions.get(instr.val);
if (f.args_count >0) {
std::vector<long double> vec(f.args_count);
for (int i=0; i<f.args_count; ++i)
vec[i] = getValue(local);
for (int i=f.args_count-1; i>=0; --i){
PolizInstruction in (TLiteral, FLOAT);
in.value = vec[i];
exec_stack.push(in);
}
}
invoke(instr.val);
break;
}
case TIfNot: {
long double v = getValue(local);
if (v==0.0) {
cursor = instr.val;
continue;
}
break;
}
case TGoto: {
cursor = instr.val;
continue;
}
case TReturn:{
was_return = true;
long double d = getValue(local);
PolizInstruction in(TLiteral);
in.val = instr.val;
in.value = (instr.val == INT)? ((long long)d) : (d);
exec_stack.push(in);
break;
}
case TRead: {
long double v;
std::cin >> v;
if (std::cin.fail()){
global_error = 1;
exec_stack.pop();
break;
}
setValue(local, v);
break;
}
case TWrite: {
int num = instr.val;
std::deque<PolizInstruction> params;
for (int i=0; i<num; ++i){
params.push_front(exec_stack.top());
exec_stack.pop();
}
if (debug)
break;
for (int i=0; i<num; ++i) {
PolizInstruction& curr = params[i];
if (curr.inst_type == TStrLit)
std::cout << params[i].str;
else if (curr.inst_type == TLiteral)
std::cout << params[i].value;
else if (curr.inst_type == TVariable){
if (curr.local)
std::cout << local.get(curr.val).value;
else
std::cout << progr->global.get(curr.val).value;
}
}
break;
}
case TWasError:{
PolizInstruction in(TLiteral);
in.val = INT;
in.value = global_error;
exec_stack.push(in);
global_error = 0;
break;
}
case TExit: {
long double d = getValue(local);
throw int(d);
}
case TPOP:
exec_stack.pop();
break;
case TOperation:{
switch (instr.val){
case T_ASS: {
long double d = getValue(local);
setValue(local, d);
break;
}
case T_OR: {
long double d1 = getValue(local);
long double d2 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d1 != 0.0 || d2 != 0.0) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_AND: {
long double d1 = getValue(local);
long double d2 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d1 != 0.0 && d2 != 0.0) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_PLUS: {
ElementTypes t1 = getType(local);
long double d1 = getValue(local);
ElementTypes t2 = getType(local);
long double d2 = getValue(local);
ElementTypes t = ( t1==FLOAT || t2==FLOAT) ? FLOAT:INT;
PolizInstruction in(TLiteral);
in.val = t;
long double res = d1 + d2;
in.value = (t == INT) ? ((long long)res) : res;
exec_stack.push(in);
break;
}
case T_MINUS: {
ElementTypes t1 = getType(local);
long double d1 = getValue(local);
ElementTypes t2 = getType(local);
long double d2 = getValue(local);
ElementTypes t = ( t1==FLOAT || t2==FLOAT) ? FLOAT:INT;
PolizInstruction in(TLiteral);
in.val = t;
long double res = d2 - d1;
in.value = (t == INT) ? ((long long)res) : res;
exec_stack.push(in);
break;
}
case T_MUL: {
ElementTypes t1 = getType(local);
long double d1 = getValue(local);
ElementTypes t2 = getType(local);
long double d2 = getValue(local);
ElementTypes t = ( t1==FLOAT || t2==FLOAT) ? FLOAT:INT;
PolizInstruction in(TLiteral);
in.val = t;
long double res = d2*d1;
in.value = (t == INT) ? ((long long)res) : res;
exec_stack.push(in);
break;
}
case T_DIV: {
ElementTypes t1 = getType(local);
long double d1 = getValue(local);
ElementTypes t2 = getType(local);
long double d2 = getValue(local);
ElementTypes t = ( t1==FLOAT || t2==FLOAT) ? FLOAT:INT;
PolizInstruction in(TLiteral);
in.val = t;
if (d1 == 0.0)
throw RuntimeException("Division by zero");
long double res = 0.0;
if (t == INT)
res = ((long long)d2) / ((long long) d1);
else
res = d2/d1;
in.value = res;
exec_stack.push(in);
break;
}
case T_MOD: {
ElementTypes t1 = getType(local);
long double d1 = getValue(local);
ElementTypes t2 = getType(local);
long double d2 = getValue(local);
ElementTypes t = ( t1==FLOAT || t2==FLOAT) ? FLOAT:INT;
if (t==FLOAT)
throw RuntimeException("Operation '%' must have 'int' arguments");
PolizInstruction in(TLiteral, INT);
if (d1 == 0.0)
throw RuntimeException("Division by zero");
long double res = ((long long)d2) % ((long long) d1);
in.value = res;
exec_stack.push(in);
break;
}
case T_DEG: {
ElementTypes t1 = getType(local);
long double d1 = getValue(local);
ElementTypes t2 = getType(local);
long double d2 = getValue(local);
ElementTypes t = ( t1==FLOAT || t2==FLOAT) ? FLOAT:INT;
PolizInstruction in(TLiteral);
in.val = t;
long double res = std::pow(d2,d1);
if (errno)
throw RuntimeException("Bad arguments in degree operation");
in.value = (t == INT) ? ((long long)res) : res;
exec_stack.push(in);
break;
}
case T_NOT: {
long double d1 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d1 == 0.0) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_EQ: {
long double d1 = getValue(local);
long double d2 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d1 == d2 ) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_NEQ: {
long double d1 = getValue(local);
long double d2 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d1 != d2 ) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_LSS: {
long double d1 = getValue(local);
long double d2 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d2 < d1 ) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_LSSEQ: {
long double d1 = getValue(local);
long double d2 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d2 <= d1 ) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_GRT: {
long double d1 = getValue(local);
long double d2 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d2 > d1 ) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_GRTEQ: {
long double d1 = getValue(local);
long double d2 = getValue(local);
PolizInstruction in(TLiteral);
in.val = INT;
in.value = (d2 >= d1 ) ? 1.0 : 0.0;
exec_stack.push(in);
break;
}
case T_MINUSUN: {
ElementTypes t1 = getType(local);
long double d1 = getValue(local);
PolizInstruction in(TLiteral);
in.val = t1;
in.value = -d1;
exec_stack.push(in);
break;
}
case T_PLUSUN: {
break;
}
default:;
}
break;
}
default:
throw RuntimeException("Wrong Poliz command");
}
++cursor;
if (was_return)
break;
}
// Returning value
if (func.return_type != VOID){
if (!was_return){
PolizInstruction in(TLiteral);
in.val = func.return_type;
in.value = 0.0;
exec_stack.push(in);
}
}
}
}
Соседние файлы в папке MyLanguage