Value Iterator::Prod(Environment &env) { Signal &sig = env.GetSignal(); Value value; if (!Next(env, value)) return Value::Nil; if (!value.Is_number()) { const Operator *pOperatorMul = env.GetOperator(OPTYPE_Mul); Value valResult(value); while (Next(env, value)) { valResult = pOperatorMul->EvalBinary(env, valResult, value, FLAG_None); if (sig.IsSignalled()) return Value::Nil; } return valResult; } Number result = value.GetNumber(); while (Next(env, value)) { if (value.Is_number()) { if (result == 0) break; result *= value.GetNumber(); } else { const Operator *pOperatorMul = env.GetOperator(OPTYPE_Mul); Value valResult(result); do { valResult = pOperatorMul->EvalBinary(env, valResult, value, FLAG_None); if (sig.IsSignalled()) return Value::Nil; } while (Next(env, value)); return valResult; } } return Value(result); }
bool Object_writer::PutValue(Environment &env, const Value &value) { Signal &sig = env.GetSignal(); String str; if (value.IsInvalid()) { return true; } else if (value.Is_number()) { str = Formatter::FormatValueList(sig, _format.c_str(), ValueList(value)); } else if (value.Is_complex()) { str = Formatter::FormatValueList(sig, _format.c_str(), ValueList(value)); } else if (value.Is_string()) { str += '"'; for (const char *p = value.GetString(); *p != '\0'; p++) { char ch = *p; str += ch; if (ch == '"') str += ch; } str += '"'; } else { sig.SetError(ERR_TypeError, "can't output in CSV format"); return false; } _pStreamDst->Print(sig, str.c_str()); return true; }
Value Iterator::FindMinMaxIndices(Environment &env, bool maxFlag) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return Value::Nil; } Value valueHit; if (!Next(env, valueHit)) return Value::Nil; Value result; int idxHit = GetIndexCur(); Object_list *pObjListResult = result.InitAsList(env); pObjListResult->Add(Value(idxHit)); Value value; while (Next(env, value)) { int cmp = Value::Compare(env, valueHit, value); if (sig.IsSignalled()) return Value::Nil; if (maxFlag) cmp = -cmp; if (cmp > 0) { int idxHit = GetIndexCur(); valueHit = value; pObjListResult->Clear(); pObjListResult->Add(Value(idxHit)); } else if (cmp == 0) { int idxHit = GetIndexCur(); pObjListResult->Add(Value(static_cast<Number>(idxHit))); } } if (sig.IsSignalled()) return Value::Nil; return result; }
Value Iterator::ToList(Environment &env, bool alwaysListFlag, bool excludeNilFlag) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return Value::Nil; } Value result; Object_list *pObjList = nullptr; size_t cnt = 0; Value value; if (alwaysListFlag) { pObjList = result.InitAsList(env); } while (Next(env, value)) { if (pObjList == nullptr && !value.IsUndefined()) { pObjList = result.InitAsList(env, cnt, Value::Nil); } if (value.IsValid()) { if (pObjList == nullptr) { pObjList = result.InitAsList(env, cnt, Value::Nil); } pObjList->Add(value); } else if (excludeNilFlag) { // nothing to do } else if (pObjList != nullptr) { pObjList->Add(value); } cnt++; } if (sig.IsSignalled()) return Value::Nil; return result; }
Value Iterator::Reduce(Environment &env, Value valueAccum, const Function *pFuncBlock) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return Value::Nil; } Value value; while (Next(env, value)) { AutoPtr<Argument> pArgSub(new Argument(pFuncBlock)); if (!pArgSub->StoreValue(env, value, valueAccum)) return Value::Nil; Value result = pFuncBlock->Eval(env, *pArgSub); if (!sig.IsSignalled()) { // nothing to do } else if (sig.IsBreak()) { result = sig.GetValue(); sig.ClearSignal(); if (result.IsValid()) return result; return valueAccum; } else if (sig.IsContinue()) { result = sig.GetValue(); sig.ClearSignal(); if (result.IsInvalid()) continue; } else if (sig.IsReturn()) { return Value::Nil; } else { return Value::Nil; } valueAccum = result; } if (sig.IsSignalled()) return Value::Nil; return valueAccum; }
size_t Iterator::Count(Environment &env, const Value &criteria) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return 0; } size_t cnt = 0; if (criteria.Is_function()) { const Function *pFunc = criteria.GetFunction(); Value value; while (Next(env, value)) { AutoPtr<Argument> pArg(new Argument(pFunc)); if (!pArg->StoreValue(env, value)) return 0; Value valueFlag = pFunc->Eval(env, *pArg); if (sig.IsSignalled()) return 0; if (valueFlag.GetBoolean()) cnt++; } if (sig.IsSignalled()) return 0; } else { Value value; while (Next(env, value)) { int cmp = Value::Compare(env, value, criteria); if (sig.IsSignalled()) return 0; if (cmp == 0) cnt++; } } return cnt; }
//----------------------------------------------------------------------------- // Stream //----------------------------------------------------------------------------- Stream::Stream(Environment &env, ULong attr) : _cntRef(1), _sig(env.GetSignal()), _attr(attr), _offsetCur(0), _blockingFlag(false), _pCodec(Codec::CreateCodecNone(true, false)) { _peek.buff = nullptr; _peek.bytes = 0; _peek.offsetRead = 0; }
void Iterator::PrintlnEach(Environment &env, Stream *pStream) { Signal &sig = env.GetSignal(); Value value; while (Next(env, value)) { pStream->Println(sig, value.ToString(false).c_str()); if (sig.IsSignalled()) break; } }
bool Iterator::Consume(Environment &env) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return false; } Value value; while (Next(env, value)) ; return !sig.IsSignalled(); }
Value Iterator::StandardDeviation(Environment &env, size_t &cnt, bool populationFlag) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return Value::Nil; } Value valueVar = Clone()->Variance(env, cnt, populationFlag); if (!valueVar.Is_number()) return Value::Nil; return Value(::sqrt(valueVar.GetNumber())); }
size_t Iterator::FindTrue(Environment &env, Value &value) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return 0; } while (Next(env, value)) { if (value.GetBoolean()) return GetIndexCur(); } return InvalidSize; }
void Iterator::PrintfEach(Environment &env, Stream *pStream, const char *format) { Signal &sig = env.GetSignal(); Value value; while (Next(env, value)) { if (value.Is_list()) { pStream->PrintFmt(sig, format, value.GetList()); } else { pStream->PrintFmt(sig, format, ValueList(value)); } if (sig.IsSignalled()) break; } }
bool Object_writer::PutLine(Environment &env, const ValueList &valList) { Signal &sig = env.GetSignal(); foreach_const (ValueList, pValue, valList) { if (pValue != valList.begin()) { _pStreamDst->PutChar(sig, ','); if (sig.IsSignalled()) return false; } if (!PutValue(env, *pValue)) return false; } _pStreamDst->PutChar(sig, '\n'); return !sig.IsSignalled(); }
size_t Iterator::GetLengthEx(Environment &env) { if (IsFinitePredictable()) return GetLength(); Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return 0; } size_t len = 0; AutoPtr<Iterator> pIterator(Clone()); Value value; for ( ; pIterator->Next(env, value); len++) ; return sig.IsSignalled()? 0 : len; }
size_t Iterator::CountTrue(Environment &env) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return 0; } size_t cnt = 0; Value value; while (Next(env, value)) { if (value.GetBoolean()) cnt++; } return cnt; }
Value Formatter::FormatIterator(Environment &env, const char *format, IteratorOwner &iterOwner) { Signal &sig = env.GetSignal(); Value result; Object_list *pObjListResult = result.InitAsList(env); ValueList valList; while (iterOwner.Next(env, valList)) { String str = FormatValueList(sig, format, valList); if (sig.IsSignalled()) return Value::Nil; pObjListResult->Add(Value(str)); } if (sig.IsSignalled()) return Value::Nil; return result; }
bool Iterator::DoesContain(Environment &env, const Value &value) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return false; } Value valueToFind; while (Next(env, valueToFind)) { int cmp = Value::Compare(env, value, valueToFind); if (sig.IsSignalled()) return false; if (cmp == 0) return true; } return false; }
Value Iterator::Or(Environment &env) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return Value::Nil; } Value value; if (!Next(env, value)) return Value::Nil; if (value.GetBoolean()) return Value(true); while (Next(env, value)) { if (value.GetBoolean()) return Value(true); } if (sig.IsSignalled()) return Value::Nil; return Value(false); }
Binary Iterator::Joinb(Environment &env) { Signal &sig = env.GetSignal(); Binary rtn; Value value; if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return rtn; } while (Next(env, value)) { if (!value.Is_binary()) { sig.SetError(ERR_ValueError, "invalid value type"); return ""; } rtn += value.GetBinary(); } return rtn; }
String Iterator::Join(Environment &env, const char *sep) { Signal &sig = env.GetSignal(); String rtn; Value value; if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return rtn; } if (Next(env, value)) { rtn += value.ToString(false); while (Next(env, value)) { rtn += sep; rtn += value.ToString(false); } } return rtn; }
Value Iterator::Average(Environment &env, size_t &cnt) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return Value::Nil; } Value valueSum = Clone()->Sum(env, cnt); if (valueSum.IsInvalid()) { return Value::Nil; } else if (valueSum.Is_number()) { return Value(valueSum.GetNumber() / static_cast<Number>(cnt)); } else if (valueSum.Is_complex()) { return Value(valueSum.GetComplex() / static_cast<Number>(cnt)); } else { const Operator *pOperatorDiv = env.GetOperator(OPTYPE_Div); return pOperatorDiv->EvalBinary(env, valueSum, Value(cnt), FLAG_None); } }
bool Object_content::Read(Environment &env, Stream &stream, Image::Format format) { Signal &sig = env.GetSignal(); int cntIcons = 0; do { IconDir iconDir; if (stream.Read(sig, &iconDir, IconDir::Size) < IconDir::Size) { sig.SetError(ERR_FormatError, "invalid ICO format"); return false; } cntIcons = Gura_UnpackUInt16(iconDir.idCount); } while (0); Int32List imageOffsets; for (int iIcon = 0; iIcon < cntIcons; iIcon++) { IconDirEntry iconDirEntry; if (stream.Read(sig, &iconDirEntry, IconDirEntry::Size) < IconDirEntry::Size) { sig.SetError(ERR_FormatError, "invalid ICO format"); return false; } long imageOffset = Gura_UnpackInt32(iconDirEntry.dwImageOffset); imageOffsets.push_back(imageOffset); } foreach (Int32List, pImageOffset, imageOffsets) { long imageOffset = *pImageOffset; if (!stream.Seek(sig, imageOffset, Stream::SeekSet)) return false; Image::BitmapInfoHeader bih; if (stream.Read(sig, &bih, Image::BitmapInfoHeader::Size) < Image::BitmapInfoHeader::Size) { sig.SetError(ERR_FormatError, "invalid ICO format"); return false; } int biWidth = Gura_UnpackInt32(bih.biWidth); int biHeight = Gura_UnpackInt32(bih.biHeight) / 2; UInt16 biBitCount = Gura_UnpackUInt16(bih.biBitCount); AutoPtr<Image> pImage(new Image(format)); if (!pImage->ReadDIBPalette(env, stream, biBitCount)) return false; if (!pImage->ReadDIB(sig, stream, biWidth, biHeight, biBitCount, true)) { return false; } _valList.push_back(Value(new Object_image(env, pImage.release()))); }
bool Stream::ReadToStream(Environment &env, Stream &streamDst, size_t bytesUnit, bool finalizeFlag, const Function *pFuncFilter) { Signal &sig = env.GetSignal(); if (!CheckReadable(sig) || !streamDst.CheckWritable(sig)) return false; Attribute attr; bool validAttrFlag = false; if (finalizeFlag) { validAttrFlag = GetAttribute(attr); } AutoPtr<Memory> pMemory(new MemoryHeap(bytesUnit)); char *buff = reinterpret_cast<char *>(pMemory->GetPointer()); for (;;) { size_t bytesRead = Read(sig, buff, bytesUnit); if (bytesRead == 0) break; if (pFuncFilter != nullptr) { Value value(new Object_binary(env, buff, bytesUnit, false)); AutoPtr<Argument> pArgSub(new Argument(pFuncFilter)); if (!pArgSub->StoreValue(env, value)) return false; Value rtn = pFuncFilter->Eval(env, *pArgSub); if (sig.IsSignalled()) return false; if (rtn.Is_binary()) { const Binary &buffRtn = rtn.GetBinary(); streamDst.Write(sig, buffRtn.data(), buffRtn.size()); if (sig.IsSignalled()) return false; continue; } } streamDst.Write(sig, buff, bytesRead); if (sig.IsSignalled()) return false; } if (sig.IsSignalled()) return false; if (finalizeFlag) { streamDst.Close(); if (sig.IsSignalled()) return false; if (validAttrFlag) streamDst.SetAttribute(attr); return true; } if (!streamDst.Flush(sig)) return false; return true; }
Value Iterator::FindMinMax(Environment &env, bool maxFlag) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return Value::Nil; } Value valueHit; if (!Next(env, valueHit)) return Value::Nil; Value value; while (Next(env, value)) { int cmp = Value::Compare(env, valueHit, value); if (sig.IsSignalled()) return Value::Nil; if (maxFlag) cmp = -cmp; if (cmp > 0) { valueHit = value; } } if (sig.IsSignalled()) return Value::Nil; return valueHit; }
size_t Iterator::Find(Environment &env, const Value &criteria, Value &value) { Signal &sig = env.GetSignal(); if (criteria.Is_function()) { if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return InvalidSize; } const Function *pFunc = criteria.GetFunction(); while (Next(env, value)) { AutoPtr<Argument> pArg(new Argument(pFunc)); if (!pArg->StoreValue(env, value)) return InvalidSize; Value valueFlag = pFunc->Eval(env, *pArg); if (sig.IsSignalled()) return InvalidSize; if (valueFlag.GetBoolean()) return GetIndexCur(); } if (sig.IsSignalled()) return InvalidSize; } else if (criteria.Is_list() || criteria.Is_iterator()) { AutoPtr<Iterator> pIteratorCriteria(criteria.CreateIterator(sig)); if (sig.IsSignalled()) return InvalidSize; if (IsInfinite() && pIteratorCriteria->IsInfinite()) { SetError_InfiniteNotAllowed(sig); return InvalidSize; } while (Next(env, value)) { Value valueCriteria; if (!pIteratorCriteria->Next(env, valueCriteria)) break; if (valueCriteria.GetBoolean()) return GetIndexCur(); } return InvalidSize; } else { while (Next(env, value)) { //int cmp = Value::Compare(env, value, criteria); //if (sig.IsSignalled()) return InvalidSize; //if (cmp == 0) return GetIndexCur(); if (value.Is(criteria)) return GetIndexCur(); } } return InvalidSize; }
Value Iterator::Sum(Environment &env, size_t &cnt) { Signal &sig = env.GetSignal(); cnt = 0; Value value; if (!Next(env, value)) return Value::Nil; if (!value.Is_number()) { const Operator *pOperatorAdd = env.GetOperator(OPTYPE_Add); Value valResult(value); cnt = 1; while (Next(env, value)) { valResult = pOperatorAdd->EvalBinary(env, valResult, value, FLAG_None); cnt++; if (sig.IsSignalled()) return Value::Nil; } return valResult; } Number result = value.GetNumber(); cnt = 1; while (Next(env, value)) { if (value.Is_number()) { result += value.GetNumber(); cnt++; } else { const Operator *pOperatorAdd = env.GetOperator(OPTYPE_Add); Value valResult(result); do { valResult = pOperatorAdd->EvalBinary(env, valResult, value, FLAG_None); cnt++; if (sig.IsSignalled()) return Value::Nil; } while (Next(env, value)); return valResult; } } return Value(result); }
//----------------------------------------------------------------------------- // Tokenizer //----------------------------------------------------------------------------- TokenId Tokenizer::Tokenize(Environment &env, Stream &stream) { Signal &sig = env.GetSignal(); _iChar = 0; if (_tokenIdPending != TOKEN_None) { TokenId tokenId = _tokenIdPending; _tokenIdPending = TOKEN_None; return tokenId; } bool escapeFlag = false; for (;;) { int chRaw = stream.GetChar(sig); if (sig.IsSignalled()) break; char ch = (chRaw < 0)? '\0' : static_cast<char>(static_cast<UChar>(chRaw)); if (ch == '\\' && !escapeFlag) { escapeFlag = true; continue; } Gura_BeginPushbackRegion(); switch (_stat) { case STAT_LineTop: { if (ch == ' ' || ch == '\t') { // nothing to do } else if (ch == '\n' || ch == '\0') { // nothing to do } else if (ch == '#') { _stat = STAT_SkipToNextLine; } else { Gura_Pushback(); _stat = STAT_Field; } break; } case STAT_SkipToNextLine: { if (ch == '\n') { if (escapeFlag) { // nothing to do } else { _stat = STAT_LineTop; } } else { // nothing to do } break; } case STAT_Field: { if (ch == ' ' || ch == '\t') { _stat = STAT_SkipWhite; _field[_iChar] = '\0'; return TOKEN_Field; } else if (ch == '\n') { if (escapeFlag) { _stat = STAT_SkipWhite; } else { _tokenIdPending = TOKEN_EOL; _stat = STAT_LineTop; } _field[_iChar] = '\0'; return TOKEN_Field; } else if (ch == '\0') { _tokenIdPending = TOKEN_EOF; _stat = STAT_FileEnd; _field[_iChar] = '\0'; return TOKEN_Field; } else { _field[_iChar++] = ch; if (_iChar >= ArraySizeOf(_field)) { SetError_FormatError(env); return TOKEN_EOF; } } break; } case STAT_SkipWhite: { if (ch == ' ' || ch == '\t') { // nothing to do } else if (ch == '\n') { if (escapeFlag) { // nothing to do } else { _stat = STAT_LineTop; return TOKEN_EOL; } } else if (ch == '\0') { _stat = STAT_LineTop; return TOKEN_EOF; } else { Gura_Pushback(); _stat = STAT_Field; } break; } case STAT_FileEnd: { // nothing to do break; } } Gura_EndPushbackRegion(); escapeFlag = false; if (ch == '\0') break; if (ch == '\n') _iLine++; } return TOKEN_EOF; }
Value Iterator::Variance(Environment &env, size_t &cnt, bool populationFlag) { Signal &sig = env.GetSignal(); if (IsInfinite()) { SetError_InfiniteNotAllowed(sig); return Value::Nil; } // this doesn't use a variance calculation formula V(x) = E(x**2) - E(x)**2 // to minimize calculation error. Value valueAve = Clone()->Average(env, cnt); if (!valueAve.IsNumberOrComplex()) return Value::Nil; Number denom = static_cast<Number>((cnt <= 1)? 1 : populationFlag? cnt : cnt - 1); Value value; if (!Next(env, value)) return Value::Nil; if (value.Is_number() && valueAve.Is_number()) { Number result; Number average = valueAve.GetNumber(); do { Number tmp = value.GetNumber() - average; result = tmp * tmp; } while (0); while (Next(env, value)) { if (value.Is_number()) { Number tmp = value.GetNumber() - average; result += tmp * tmp; } else if (value.Is_complex()) { while (Next(env, value)) { if (value.IsNumberOrComplex()) { Complex tmp = value.GetComplex() - average; result += std::norm(tmp); } else { SetError_InvalidDataTypeOfElement(sig); return Value::Nil; } } } else { SetError_InvalidDataTypeOfElement(sig); return Value::Nil; } } if (sig.IsSignalled()) return Value::Nil; return Value(result / denom); } else if (value.IsNumberOrComplex()) { Number result; Complex average = valueAve.GetComplex(); do { Complex tmp = value.GetComplex() - average; result = std::norm(tmp); } while (0); while (Next(env, value)) { if (value.IsNumberOrComplex()) { Complex tmp = value.GetComplex() - average; result += std::norm(tmp); } else { SetError_InvalidDataTypeOfElement(sig); return Value::Nil; } } if (sig.IsSignalled()) return Value::Nil; return Value(result / denom); } else { SetError_InvalidDataTypeOfElement(sig); return Value::Nil; } }