1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 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 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
|
#include "stdafx.h"
#include "Int.h"
#include "Core/Array.h"
#include "Core/Hash.h"
#include "Core/Str.h"
#include "Core/Io/Serialization.h"
#include "Core/Io/SerializationUtils.h"
#include "Function.h"
#include "Number.h"
namespace storm {
using namespace code;
Type *createInt(Str *name, Size size, GcType *type) {
return new (name) IntType(name, type);
}
// Note: Works for both float and double.
static void intToFloat(InlineParams p) {
if (!p.result->needed())
return;
*p.state->l << icastf(p.result->location(p.state), p.param(0));
}
static Int intRead(IStream *from) {
return from->readInt();
}
static Int intReadS(ObjIStream *from) {
return Serialize<Int>::read(from);
}
static void intWrite(Int v, OStream *to) {
to->writeInt(v);
}
static void intWriteS(Int v, ObjOStream *to) {
Serialize<Int>::write(v, to);
}
static void intToS(Int &v, StrBuf *to) {
*to << v;
}
IntType::IntType(Str *name, GcType *type) : Type(name, typeValue | typeFinal, Size::sInt, type, null) {}
Bool IntType::loadAll() {
Array<Value> *r = new (this) Array<Value>(1, Value(this, true));
Array<Value> *rr = new (this) Array<Value>(2, Value(this, true));
Array<Value> *v = new (this) Array<Value>(1, Value(this, false));
Array<Value> *vv = new (this) Array<Value>(2, Value(this, false));
Array<Value> *rv = new (this) Array<Value>(2, Value(this, true));
rv->at(1) = Value(this);
Value b(StormInfo<Bool>::type(engine));
add(inlinedFunction(engine, Value(this), S("+"), vv, fnPtr(engine, &numAdd))->makePure());
add(inlinedFunction(engine, Value(this), S("-"), vv, fnPtr(engine, &numSub))->makePure());
add(inlinedFunction(engine, Value(this), S("*"), vv, fnPtr(engine, &numMul))->makePure());
add(inlinedFunction(engine, Value(this), S("/"), vv, fnPtr(engine, &numIDiv))->makePure());
add(inlinedFunction(engine, Value(this), S("%"), vv, fnPtr(engine, &numIMod))->makePure());
add(inlinedFunction(engine, Value(this), S("-"), v, fnPtr(engine, &numINeg))->makePure());
add(inlinedFunction(engine, b, S("=="), vv, fnPtr(engine, &numCmp<ifEqual>))->makePure());
add(inlinedFunction(engine, b, S("!="), vv, fnPtr(engine, &numCmp<ifNotEqual>))->makePure());
add(inlinedFunction(engine, b, S("<="), vv, fnPtr(engine, &numCmp<ifLessEqual>))->makePure());
add(inlinedFunction(engine, b, S(">="), vv, fnPtr(engine, &numCmp<ifGreaterEqual>))->makePure());
add(inlinedFunction(engine, b, S("<"), vv, fnPtr(engine, &numCmp<ifLess>))->makePure());
add(inlinedFunction(engine, b, S(">"), vv, fnPtr(engine, &numCmp<ifGreater>))->makePure());
add(inlinedFunction(engine, Value(this), S("*++"), r, fnPtr(engine, &numPostfixInc<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("++*"), r, fnPtr(engine, &numPrefixInc<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("*--"), r, fnPtr(engine, &numPostfixDec<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("--*"), r, fnPtr(engine, &numPrefixDec<Int>))->makePure());
add(inlinedFunction(engine, Value(this, true), S("="), rv, fnPtr(engine, &numAssign<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("+="), rv, fnPtr(engine, &numInc<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("-="), rv, fnPtr(engine, &numDec<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("*="), rv, fnPtr(engine, &numScale<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("/="), rv, fnPtr(engine, &numIDivScale<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("%="), rv, fnPtr(engine, &numIModEq<Int>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, rr, fnPtr(engine, &numCopyCtor<Int>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, r, fnPtr(engine, &numInit<Int>))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Nat>::type(engine)), S("nat"), v, fnPtr(engine, &icast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Byte>::type(engine)), S("byte"), v, fnPtr(engine, &icast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Long>::type(engine)), S("long"), v, fnPtr(engine, &icast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Word>::type(engine)), S("word"), v, fnPtr(engine, &icast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Float>::type(engine)), S("float"), v, fnPtr(engine, &intToFloat))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Double>::type(engine)), S("double"), v, fnPtr(engine, &intToFloat))->makePure());
Value n(StormInfo<Nat>::type(engine));
add(nativeFunction(engine, n, S("hash"), v, address(&intHash))->makePure());
add(inlinedFunction(engine, Value(this), S("min"), vv, fnPtr(engine, &numMin<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("max"), vv, fnPtr(engine, &numMax<Int>))->makePure());
add(inlinedFunction(engine, Value(this), S("delta"), vv, fnPtr(engine, &numDelta<Int>))->makePure());
Array<Value> *rs = new (this) Array<Value>(2, Value(this, true));
rs->at(1) = StormInfo<StrBuf>::type(engine);
add(nativeFunction(engine, Value(), S("toS"), rs, address(&intToS)));
Array<Value> *is = new (this) Array<Value>(1, Value(StormInfo<IStream>::type(engine)));
add(nativeFunction(engine, Value(this), S("read"), is, address(&intRead)));
is = new (this) Array<Value>(1, Value(StormInfo<ObjIStream>::type(engine)));
add(nativeFunction(engine, Value(this), S("read"), is, address(&intReadS)));
Array<Value> *os = new (this) Array<Value>(2, Value(this, false));
os->at(1) = Value(StormInfo<OStream>::type(engine));
add(nativeFunction(engine, Value(), S("write"), os, address(&intWrite)));
os = new (this) Array<Value>(2, Value(this, false));
os->at(1) = Value(StormInfo<ObjOStream>::type(engine));
add(nativeFunction(engine, Value(), S("write"), os, address(&intWriteS)));
return Type::loadAll();
}
Type *createNat(Str *name, Size size, GcType *type) {
return new (name) NatType(name, type);
}
static void castNat(InlineParams p) {
p.allocRegs(0);
*p.state->l << ucast(intRel(p.regParam(0), Offset()), p.param(1));
}
static void natToFloat(InlineParams p) {
if (!p.result->needed())
return;
*p.state->l << ucastf(p.result->location(p.state), p.param(0));
}
static Nat natRead(IStream *from) {
return from->readNat();
}
static Nat natReadS(ObjIStream *from) {
return Serialize<Nat>::read(from);
}
static void natWrite(Nat v, OStream *to) {
to->writeNat(v);
}
static void natWriteS(Nat v, ObjOStream *to) {
Serialize<Nat>::write(v, to);
}
static void natToS(Nat &v, StrBuf *to) {
*to << v;
}
NatType::NatType(Str *name, GcType *type) : Type(name, typeValue | typeFinal, Size::sNat, type, null) {}
Bool NatType::loadAll() {
Array<Value> *r = new (this) Array<Value>(1, Value(this, true));
Array<Value> *rr = new (this) Array<Value>(2, Value(this, true));
Array<Value> *v = new (this) Array<Value>(1, Value(this, false));
Array<Value> *vv = new (this) Array<Value>(2, Value(this, false));
Array<Value> *rv = new (this) Array<Value>(2, Value(this, true));
rv->at(1) = Value(this);
Value b(StormInfo<Bool>::type(engine));
Array<Value> *vb = new (this) Array<Value>(2, Value(this, false));
Array<Value> *rb = new (this) Array<Value>(2, Value(this, true));
vb->at(1) = rb->at(1) = Value(StormInfo<Byte>::type(engine));
add(inlinedFunction(engine, Value(this), S("+"), vv, fnPtr(engine, &numAdd))->makePure());
add(inlinedFunction(engine, Value(this), S("-"), vv, fnPtr(engine, &numSub))->makePure());
add(inlinedFunction(engine, Value(this), S("*"), vv, fnPtr(engine, &numMul))->makePure());
add(inlinedFunction(engine, Value(this), S("/"), vv, fnPtr(engine, &numUDiv))->makePure());
add(inlinedFunction(engine, Value(this), S("%"), vv, fnPtr(engine, &numUMod))->makePure());
add(inlinedFunction(engine, b, S("=="), vv, fnPtr(engine, &numCmp<ifEqual>))->makePure());
add(inlinedFunction(engine, b, S("!="), vv, fnPtr(engine, &numCmp<ifNotEqual>))->makePure());
add(inlinedFunction(engine, b, S("<="), vv, fnPtr(engine, &numCmp<ifBelowEqual>))->makePure());
add(inlinedFunction(engine, b, S(">="), vv, fnPtr(engine, &numCmp<ifAboveEqual>))->makePure());
add(inlinedFunction(engine, b, S("<"), vv, fnPtr(engine, &numCmp<ifBelow>))->makePure());
add(inlinedFunction(engine, b, S(">"), vv, fnPtr(engine, &numCmp<ifAbove>))->makePure());
add(inlinedFunction(engine, Value(this), S("*++"), r, fnPtr(engine, &numPostfixInc<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("++*"), r, fnPtr(engine, &numPrefixInc<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("*--"), r, fnPtr(engine, &numPostfixDec<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("--*"), r, fnPtr(engine, &numPrefixDec<Nat>))->makePure());
add(inlinedFunction(engine, Value(this, true), S("="), rv, fnPtr(engine, &numAssign<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("+="), rv, fnPtr(engine, &numInc<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("-="), rv, fnPtr(engine, &numDec<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("*="), rv, fnPtr(engine, &numScale<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("/="), rv, fnPtr(engine, &numUDivScale<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("%="), rv, fnPtr(engine, &numUModEq<Nat>))->makePure());
// Bitwise operators.
add(inlinedFunction(engine, Value(this), S("&"), vv, fnPtr(engine, &numAnd))->makePure());
add(inlinedFunction(engine, Value(this), S("|"), vv, fnPtr(engine, &numOr))->makePure());
add(inlinedFunction(engine, Value(this), S("^"), vv, fnPtr(engine, &numXor))->makePure());
add(inlinedFunction(engine, Value(this), S("~"), v, fnPtr(engine, &numNot))->makePure());
add(inlinedFunction(engine, Value(this), S("<<"), vb, fnPtr(engine, &numShl))->makePure());
add(inlinedFunction(engine, Value(this), S(">>"), vb, fnPtr(engine, &numShr))->makePure());
add(inlinedFunction(engine, Value(this), S("&="), rv, fnPtr(engine, &numAndEq<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("|="), rv, fnPtr(engine, &numOrEq<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("^="), rv, fnPtr(engine, &numXorEq<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("<<="), rb, fnPtr(engine, &numShlEq<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S(">>="), rb, fnPtr(engine, &numShrEq<Nat>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, rr, fnPtr(engine, &numCopyCtor<Nat>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, r, fnPtr(engine, &numInit<Nat>))->makePure());
add(inlinedFunction(engine, Value(), Type::CTOR, rb, fnPtr(engine, &castNat))->makeAutoCast()->makePure());
add(inlinedFunction(engine, Value(StormInfo<Int>::type(engine)), S("int"), v, fnPtr(engine, &ucast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Byte>::type(engine)), S("byte"), v, fnPtr(engine, &ucast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Long>::type(engine)), S("long"), v, fnPtr(engine, &ucast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Word>::type(engine)), S("word"), v, fnPtr(engine, &ucast))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Float>::type(engine)), S("float"), v, fnPtr(engine, &natToFloat))->makePure());
add(inlinedFunction(engine, Value(StormInfo<Double>::type(engine)), S("double"), v, fnPtr(engine, &natToFloat))->makePure());
add(nativeFunction(engine, Value(this), S("hash"), v, address(&natHash))->makePure());
add(inlinedFunction(engine, Value(this), S("min"), vv, fnPtr(engine, &numMin<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("max"), vv, fnPtr(engine, &numMax<Nat>))->makePure());
add(inlinedFunction(engine, Value(this), S("delta"), vv, fnPtr(engine, &numDelta<Nat>))->makePure());
Array<Value> *rs = new (this) Array<Value>(2, Value(this, true));
rs->at(1) = StormInfo<StrBuf>::type(engine);
add(nativeFunction(engine, Value(), S("toS"), rs, address(&natToS)));
Array<Value> *is = new (this) Array<Value>(1, Value(StormInfo<IStream>::type(engine)));
add(nativeFunction(engine, Value(this), S("read"), is, address(&natRead)));
is = new (this) Array<Value>(1, Value(StormInfo<ObjIStream>::type(engine)));
add(nativeFunction(engine, Value(this), S("read"), is, address(&natReadS)));
Array<Value> *os = new (this) Array<Value>(2, Value(this, false));
os->at(1) = Value(StormInfo<OStream>::type(engine));
add(nativeFunction(engine, Value(), S("write"), os, address(&natWrite)));
os = new (this) Array<Value>(2, Value(this, false));
os->at(1) = Value(StormInfo<ObjOStream>::type(engine));
add(nativeFunction(engine, Value(), S("write"), os, address(&natWriteS)));
return Type::loadAll();
}
}
|