19 |
bool isNoOperation(StatementRef statement) { |
bool isNoOperation(StatementRef statement) { |
20 |
return statement->statementType() == STMT_NOOP; |
return statement->statementType() == STMT_NOOP; |
21 |
} |
} |
22 |
|
|
23 |
|
String acceptedArgTypesStr(VMFunction* fn, vmint iArg) { |
24 |
|
static const ExprType_t allTypes[] = { |
25 |
|
INT_EXPR, |
26 |
|
INT_ARR_EXPR, |
27 |
|
REAL_EXPR, |
28 |
|
REAL_ARR_EXPR, |
29 |
|
STRING_EXPR, |
30 |
|
STRING_ARR_EXPR, |
31 |
|
}; |
32 |
|
const size_t nTypes = sizeof(allTypes) / sizeof(ExprType_t); |
33 |
|
|
34 |
|
std::vector<ExprType_t> supportedTypes; |
35 |
|
for (int iType = 0; iType < nTypes; ++iType) { |
36 |
|
const ExprType_t& type = allTypes[iType]; |
37 |
|
if (fn->acceptsArgType(iArg, type)) |
38 |
|
supportedTypes.push_back(type); |
39 |
|
} |
40 |
|
assert(!supportedTypes.empty()); |
41 |
|
|
42 |
|
if (supportedTypes.size() == 1) { |
43 |
|
return typeStr(*supportedTypes.begin()); |
44 |
|
} else { |
45 |
|
String s = "either "; |
46 |
|
for (size_t i = 0; i < supportedTypes.size(); ++i) { |
47 |
|
const ExprType_t& type = supportedTypes[i]; |
48 |
|
if (i == 0) { |
49 |
|
s += typeStr(type); |
50 |
|
} else if (i == supportedTypes.size() - 1) { |
51 |
|
s += " or " + typeStr(type); |
52 |
|
} else { |
53 |
|
s += ", " + typeStr(type); |
54 |
|
} |
55 |
|
} |
56 |
|
return s; |
57 |
|
} |
58 |
|
} |
59 |
|
|
60 |
Node::Node() { |
Node::Node() { |
61 |
} |
} |
188 |
|
|
189 |
void IntLiteral::dump(int level) { |
void IntLiteral::dump(int level) { |
190 |
printIndents(level); |
printIndents(level); |
191 |
printf("IntLiteral %lld\n", value); |
printf("IntLiteral %" PRId64 "\n", (int64_t)value); |
192 |
} |
} |
193 |
|
|
194 |
RealLiteral::RealLiteral(const RealLitDef& def) : |
RealLiteral::RealLiteral(const RealLitDef& def) : |
639 |
} |
} |
640 |
|
|
641 |
VMIntArrayExpr* FunctionCall::asIntArray() const { |
VMIntArrayExpr* FunctionCall::asIntArray() const { |
642 |
|
//FIXME: asIntArray() not intended for evaluation semantics (for both |
643 |
|
// performance reasons with arrays, but also to prevent undesired value |
644 |
|
// mutation by implied (hidden) evaluation, as actually done here. We must |
645 |
|
// force function evaluation here though, because we need it for function |
646 |
|
// calls to be evaluated at all. This issue should be addressed cleanly by |
647 |
|
// adjusting the API appropriately. |
648 |
|
FunctionCall* rwSelf = const_cast<FunctionCall*>(this); |
649 |
|
rwSelf->result = rwSelf->execVMFn(); |
650 |
|
|
651 |
if (!result) return 0; |
if (!result) return 0; |
652 |
VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue()); |
VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue()); |
653 |
return intArrExpr; |
return intArrExpr; |
654 |
} |
} |
655 |
|
|
656 |
VMRealArrayExpr* FunctionCall::asRealArray() const { |
VMRealArrayExpr* FunctionCall::asRealArray() const { |
657 |
|
//FIXME: asRealArray() not intended for evaluation semantics (for both |
658 |
|
// performance reasons with arrays, but also to prevent undesired value |
659 |
|
// mutation by implied (hidden) evaluation, as actually done here. We must |
660 |
|
// force function evaluation here though, because we need it for function |
661 |
|
// calls to be evaluated at all. This issue should be addressed cleanly by |
662 |
|
// adjusting the API appropriately. |
663 |
|
FunctionCall* rwSelf = const_cast<FunctionCall*>(this); |
664 |
|
rwSelf->result = rwSelf->execVMFn(); |
665 |
|
|
666 |
if (!result) return 0; |
if (!result) return 0; |
667 |
VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue()); |
VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue()); |
668 |
return realArrExpr; |
return realArrExpr; |
723 |
.ctx = decl.ctx, |
.ctx = decl.ctx, |
724 |
.isPolyphonic = decl.isPolyphonic, |
.isPolyphonic = decl.isPolyphonic, |
725 |
.isConst = decl.isConst, |
.isConst = decl.isConst, |
|
.isFinal = decl.isFinal, |
|
726 |
.elements = decl.elements, |
.elements = decl.elements, |
727 |
.memPos = ( |
.memPos = ( |
728 |
(!decl.ctx) ? 0 : |
(!decl.ctx) ? 0 : |
736 |
postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) : |
postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) : |
737 |
postfixInc(decl.ctx->globalUnitFactorCount, decl.elements) |
postfixInc(decl.ctx->globalUnitFactorCount, decl.elements) |
738 |
), |
), |
739 |
.unitType = decl.unitType |
.unitType = decl.unitType, |
740 |
|
.isFinal = decl.isFinal, |
741 |
}), |
}), |
742 |
Unit(decl.unitType) |
Unit(decl.unitType) |
743 |
{ |
{ |
779 |
.ctx = decl.ctx, |
.ctx = decl.ctx, |
780 |
.isPolyphonic = decl.isPolyphonic, |
.isPolyphonic = decl.isPolyphonic, |
781 |
.isConst = decl.isConst, |
.isConst = decl.isConst, |
|
.isFinal = decl.isFinal, |
|
782 |
.elements = decl.elements, |
.elements = decl.elements, |
783 |
.memPos = ( |
.memPos = ( |
784 |
(!decl.ctx) ? 0 : |
(!decl.ctx) ? 0 : |
792 |
postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) : |
postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) : |
793 |
postfixInc(decl.ctx->globalUnitFactorCount, decl.elements) |
postfixInc(decl.ctx->globalUnitFactorCount, decl.elements) |
794 |
), |
), |
795 |
.unitType = decl.unitType |
.unitType = decl.unitType, |
796 |
|
.isFinal = decl.isFinal, |
797 |
}), |
}), |
798 |
Unit(decl.unitType) |
Unit(decl.unitType) |
799 |
{ |
{ |
835 |
.ctx = def.ctx, |
.ctx = def.ctx, |
836 |
.isPolyphonic = false, |
.isPolyphonic = false, |
837 |
.isConst = true, |
.isConst = true, |
|
.isFinal = def.isFinal, |
|
838 |
.elements = 1, |
.elements = 1, |
839 |
.memPos = def.memPos, |
.memPos = def.memPos, |
840 |
.unitFactorMemPos = def.unitFactorMemPos, |
.unitFactorMemPos = def.unitFactorMemPos, |
841 |
.unitType = def.unitType |
.unitType = def.unitType, |
842 |
|
.isFinal = def.isFinal, |
843 |
}), |
}), |
844 |
Unit(def.unitType), |
Unit(def.unitType), |
845 |
value(def.value), unitPrefixFactor(def.unitFactor) |
value(def.value), unitPrefixFactor(def.unitFactor) |
863 |
|
|
864 |
void ConstIntVariable::dump(int level) { |
void ConstIntVariable::dump(int level) { |
865 |
printIndents(level); |
printIndents(level); |
866 |
printf("ConstIntVariable val=%lld\n", value); |
printf("ConstIntVariable val=%" PRId64 "\n", (int64_t)value); |
867 |
} |
} |
868 |
|
|
869 |
ConstRealVariable::ConstRealVariable(const RealVarDef& def) : |
ConstRealVariable::ConstRealVariable(const RealVarDef& def) : |
871 |
.ctx = def.ctx, |
.ctx = def.ctx, |
872 |
.isPolyphonic = false, |
.isPolyphonic = false, |
873 |
.isConst = true, |
.isConst = true, |
|
.isFinal = def.isFinal, |
|
874 |
.elements = 1, |
.elements = 1, |
875 |
.memPos = def.memPos, |
.memPos = def.memPos, |
876 |
.unitFactorMemPos = def.unitFactorMemPos, |
.unitFactorMemPos = def.unitFactorMemPos, |
877 |
.unitType = def.unitType |
.unitType = def.unitType, |
878 |
|
.isFinal = def.isFinal, |
879 |
}), |
}), |
880 |
Unit(def.unitType), |
Unit(def.unitType), |
881 |
value(def.value), unitPrefixFactor(def.unitFactor) |
value(def.value), unitPrefixFactor(def.unitFactor) |
900 |
.ctx = NULL, |
.ctx = NULL, |
901 |
.isPolyphonic = false, |
.isPolyphonic = false, |
902 |
.isConst = false, // may or may not be modifyable though! |
.isConst = false, // may or may not be modifyable though! |
|
.isFinal = false, |
|
903 |
.elements = 0, |
.elements = 0, |
904 |
.memPos = 0, |
.memPos = 0, |
905 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
906 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
907 |
|
.isFinal = false, |
908 |
}), |
}), |
909 |
Unit(VM_NO_UNIT), |
Unit(VM_NO_UNIT), |
910 |
name(name), ptr(ptr) |
name(name), ptr(ptr) |
931 |
.ctx = decl.ctx, |
.ctx = decl.ctx, |
932 |
.isPolyphonic = true, |
.isPolyphonic = true, |
933 |
.isConst = decl.isConst, |
.isConst = decl.isConst, |
|
.isFinal = decl.isFinal, |
|
934 |
.elements = 1, |
.elements = 1, |
935 |
.memPos = 0, |
.memPos = 0, |
936 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
937 |
.unitType = decl.unitType |
.unitType = decl.unitType, |
938 |
|
.isFinal = decl.isFinal, |
939 |
}), |
}), |
940 |
Unit(decl.unitType) |
Unit(decl.unitType) |
941 |
{ |
{ |
951 |
.ctx = decl.ctx, |
.ctx = decl.ctx, |
952 |
.isPolyphonic = true, |
.isPolyphonic = true, |
953 |
.isConst = decl.isConst, |
.isConst = decl.isConst, |
|
.isFinal = decl.isFinal, |
|
954 |
.elements = 1, |
.elements = 1, |
955 |
.memPos = 0, |
.memPos = 0, |
956 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
957 |
.unitType = decl.unitType |
.unitType = decl.unitType, |
958 |
|
.isFinal = decl.isFinal, |
959 |
}), |
}), |
960 |
Unit(decl.unitType) |
Unit(decl.unitType) |
961 |
{ |
{ |
971 |
.ctx = ctx, |
.ctx = ctx, |
972 |
.isPolyphonic = false, |
.isPolyphonic = false, |
973 |
.isConst = false, |
.isConst = false, |
|
.isFinal = false, |
|
974 |
.elements = 0, |
.elements = 0, |
975 |
.memPos = 0, |
.memPos = 0, |
976 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
977 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
978 |
|
.isFinal = false, |
979 |
}) |
}) |
980 |
{ |
{ |
981 |
values.resize(size); |
values.resize(size); |
992 |
.ctx = ctx, |
.ctx = ctx, |
993 |
.isPolyphonic = false, |
.isPolyphonic = false, |
994 |
.isConst = _bConst, |
.isConst = _bConst, |
|
.isFinal = false, |
|
995 |
.elements = 0, |
.elements = 0, |
996 |
.memPos = 0, |
.memPos = 0, |
997 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
998 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
999 |
|
.isFinal = false, |
1000 |
}) |
}) |
1001 |
{ |
{ |
1002 |
this->values.resize(size); |
this->values.resize(size); |
1015 |
.ctx = ctx, |
.ctx = ctx, |
1016 |
.isPolyphonic = false, |
.isPolyphonic = false, |
1017 |
.isConst = bConst, |
.isConst = bConst, |
|
.isFinal = false, |
|
1018 |
.elements = 0, |
.elements = 0, |
1019 |
.memPos = 0, |
.memPos = 0, |
1020 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
1021 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
1022 |
|
.isFinal = false, |
1023 |
}) |
}) |
1024 |
{ |
{ |
1025 |
} |
} |
1052 |
printf("\n"); |
printf("\n"); |
1053 |
printIndents(level+1); |
printIndents(level+1); |
1054 |
} |
} |
1055 |
printf("%lld, ", values[i]); |
printf("%" PRId64 ", ", (int64_t)values[i]); |
1056 |
} |
} |
1057 |
printIndents(level); |
printIndents(level); |
1058 |
printf(")\n"); |
printf(")\n"); |
1063 |
.ctx = ctx, |
.ctx = ctx, |
1064 |
.isPolyphonic = false, |
.isPolyphonic = false, |
1065 |
.isConst = false, |
.isConst = false, |
|
.isFinal = false, |
|
1066 |
.elements = 0, |
.elements = 0, |
1067 |
.memPos = 0, |
.memPos = 0, |
1068 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
1069 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
1070 |
|
.isFinal = false, |
1071 |
}) |
}) |
1072 |
{ |
{ |
1073 |
values.resize(size); |
values.resize(size); |
1084 |
.ctx = ctx, |
.ctx = ctx, |
1085 |
.isPolyphonic = false, |
.isPolyphonic = false, |
1086 |
.isConst = _bConst, |
.isConst = _bConst, |
|
.isFinal = false, |
|
1087 |
.elements = 0, |
.elements = 0, |
1088 |
.memPos = 0, |
.memPos = 0, |
1089 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
1090 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
1091 |
|
.isFinal = false, |
1092 |
}) |
}) |
1093 |
{ |
{ |
1094 |
this->values.resize(size); |
this->values.resize(size); |
1107 |
.ctx = ctx, |
.ctx = ctx, |
1108 |
.isPolyphonic = false, |
.isPolyphonic = false, |
1109 |
.isConst = bConst, |
.isConst = bConst, |
|
.isFinal = false, |
|
1110 |
.elements = 0, |
.elements = 0, |
1111 |
.memPos = 0, |
.memPos = 0, |
1112 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
1113 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
1114 |
|
.isFinal = false, |
1115 |
}) |
}) |
1116 |
{ |
{ |
1117 |
} |
} |
1176 |
.ctx = NULL, |
.ctx = NULL, |
1177 |
.isPolyphonic = (array) ? array->isPolyphonic() : false, |
.isPolyphonic = (array) ? array->isPolyphonic() : false, |
1178 |
.isConst = (array) ? array->isConstExpr() : false, |
.isConst = (array) ? array->isConstExpr() : false, |
|
.isFinal = false, |
|
1179 |
.elements = 0, |
.elements = 0, |
1180 |
.memPos = 0, |
.memPos = 0, |
1181 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
1182 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
1183 |
|
.isFinal = false, |
1184 |
}), |
}), |
1185 |
Unit(VM_NO_UNIT), |
Unit(VM_NO_UNIT), |
1186 |
array(array), index(arrayIndex), currentIndex(-1) |
array(array), index(arrayIndex), currentIndex(-1) |
1187 |
{ |
{ |
1188 |
} |
} |
1189 |
|
|
1190 |
void IntArrayElement::assign(Expression* expr) { |
void IntArrayElement::assign(Expression* expr) { |
1227 |
.ctx = NULL, |
.ctx = NULL, |
1228 |
.isPolyphonic = (array) ? array->isPolyphonic() : false, |
.isPolyphonic = (array) ? array->isPolyphonic() : false, |
1229 |
.isConst = (array) ? array->isConstExpr() : false, |
.isConst = (array) ? array->isConstExpr() : false, |
|
.isFinal = false, |
|
1230 |
.elements = 0, |
.elements = 0, |
1231 |
.memPos = 0, |
.memPos = 0, |
1232 |
.unitFactorMemPos = 0, |
.unitFactorMemPos = 0, |
1233 |
.unitType = VM_NO_UNIT |
.unitType = VM_NO_UNIT, |
1234 |
|
.isFinal = false, |
1235 |
}), |
}), |
1236 |
Unit(VM_NO_UNIT), |
Unit(VM_NO_UNIT), |
1237 |
array(array), index(arrayIndex), currentIndex(-1) |
array(array), index(arrayIndex), currentIndex(-1) |
1285 |
StringVariable::StringVariable(ParserContext* ctx, bool bConst) : |
StringVariable::StringVariable(ParserContext* ctx, bool bConst) : |
1286 |
Variable({ |
Variable({ |
1287 |
.ctx = ctx, |
.ctx = ctx, |
1288 |
|
.isConst = bConst, |
1289 |
.memPos = 0, |
.memPos = 0, |
|
.isConst = bConst |
|
1290 |
}) |
}) |
1291 |
{ |
{ |
1292 |
} |
} |
1303 |
|
|
1304 |
void StringVariable::dump(int level) { |
void StringVariable::dump(int level) { |
1305 |
printIndents(level); |
printIndents(level); |
1306 |
printf("StringVariable memPos=%lld\n", memPos); |
printf("StringVariable memPos=%" PRId64 "\n", (int64_t)memPos); |
1307 |
} |
} |
1308 |
|
|
1309 |
ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value) |
ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value) |
1373 |
printIndents(level); |
printIndents(level); |
1374 |
if (select) |
if (select) |
1375 |
if (select->isConstExpr()) |
if (select->isConstExpr()) |
1376 |
printf("Case select %lld\n", select->evalInt()); |
printf("Case select %" PRId64 "\n", (int64_t)select->evalInt()); |
1377 |
else |
else |
1378 |
printf("Case select [runtime expr]\n"); |
printf("Case select [runtime expr]\n"); |
1379 |
else |
else |
1383 |
CaseBranch& branch = branches[i]; |
CaseBranch& branch = branches[i]; |
1384 |
if (branch.from && branch.to) |
if (branch.from && branch.to) |
1385 |
if (branch.from->isConstExpr() && branch.to->isConstExpr()) |
if (branch.from->isConstExpr() && branch.to->isConstExpr()) |
1386 |
printf("case %lld to %lld\n", branch.from->evalInt(), branch.to->evalInt()); |
printf("case %" PRId64 " to %" PRId64 "\n", (int64_t)branch.from->evalInt(), (int64_t)branch.to->evalInt()); |
1387 |
else if (branch.from->isConstExpr() && !branch.to->isConstExpr()) |
else if (branch.from->isConstExpr() && !branch.to->isConstExpr()) |
1388 |
printf("case %lld to [runtime expr]\n", branch.from->evalInt()); |
printf("case %" PRId64 " to [runtime expr]\n", (int64_t)branch.from->evalInt()); |
1389 |
else if (!branch.from->isConstExpr() && branch.to->isConstExpr()) |
else if (!branch.from->isConstExpr() && branch.to->isConstExpr()) |
1390 |
printf("case [runtime expr] to %lld\n", branch.to->evalInt()); |
printf("case [runtime expr] to %" PRId64 "\n", (int64_t)branch.to->evalInt()); |
1391 |
else |
else |
1392 |
printf("case [runtime expr] to [runtime expr]\n"); |
printf("case [runtime expr] to [runtime expr]\n"); |
1393 |
else if (branch.from) |
else if (branch.from) |
1394 |
if (branch.from->isConstExpr()) |
if (branch.from->isConstExpr()) |
1395 |
printf("case %lld\n", branch.from->evalInt()); |
printf("case %" PRId64 "\n", (int64_t)branch.from->evalInt()); |
1396 |
else |
else |
1397 |
printf("case [runtime expr]\n"); |
printf("case [runtime expr]\n"); |
1398 |
else |
else |
1431 |
printIndents(level); |
printIndents(level); |
1432 |
if (m_condition) |
if (m_condition) |
1433 |
if (m_condition->isConstExpr()) |
if (m_condition->isConstExpr()) |
1434 |
printf("while (%lld) {\n", m_condition->evalInt()); |
printf("while (%" PRId64 ") {\n", (int64_t)m_condition->evalInt()); |
1435 |
else |
else |
1436 |
printf("while ([runtime expr]) {\n"); |
printf("while ([runtime expr]) {\n"); |
1437 |
else |
else |
1898 |
.value = it->second |
.value = it->second |
1899 |
}); |
}); |
1900 |
vartable[it->first] = ref; |
vartable[it->first] = ref; |
1901 |
|
} |
1902 |
|
} |
1903 |
|
|
1904 |
|
void ParserContext::registerBuiltInConstRealVariables(const std::map<String,vmfloat>& vars) { |
1905 |
|
for (std::map<String,vmfloat>::const_iterator it = vars.begin(); |
1906 |
|
it != vars.end(); ++it) |
1907 |
|
{ |
1908 |
|
ConstRealVariableRef ref = new ConstRealVariable({ |
1909 |
|
.value = it->second |
1910 |
|
}); |
1911 |
|
vartable[it->first] = ref; |
1912 |
} |
} |
1913 |
} |
} |
1914 |
|
|