text:
Changelog
=========

* **2013-11-28**: [BC BREAK] the alias attribute of the <template-by-class> is
  renamed to class in the bundle configuration.

1.1.0
-----

* **2013-10-14**: The route enhancers now have a non-default priority so that
  the order is defined and you can add your own enhancers.

1.1.0-RC8
---------

* **2013-10-08**: The idPrefix is now used as a filter in getRouteByName() and
  getRoutesByNames() in the PHPCR RouteProvider. This means its no longer
  possible to get routes that are not children of a path that begins with
  idPrefix.

1.1.0-RC5
---------

* **2013-09-04**: If the route matched a pattern with a format extension, the
  format extension is no longer set as route a default.
* **2013-09-04**: Marked ContentAwareGenerator as obsolete, use
  ContentAwareGenerator from the CMF routing component directly instead. This
  class will be removed in 1.2.
* **2013-08-09**: dynamic.generic_controller is now defaulting to null instead
  of the controller from CmfContentBundle. CmfCoreBundle is prepending the
  CmfContentBundle generic controller if that bundle is present. If you do not
  have Core and Content, you need to configure the value explicitly if you want
  routes specifying a template to use the generic controller or have
  template_by_class mapping configuration.

1.1.0-RC2
---------

* **2013-08-04**: [PHPCR-ODM] Fixed the configuration of the LocaleListener to
  make routes again automatically provide the _locale based on their repository
  path if the bundle is configured with locales.
* **2013-08-04**: [Bundle] Only build the compiler passes for ORM and PHPCR-ODM
  if all required repositories are present.

1.1.0-RC1
---------

* **2013-07-31**: [EventDispatcher] Added events to the dynamic router at the
  start of match and matchRequest.
* **2013-07-29**: [DependencyInjection] restructured `phpcr_provider` config
  into `persistence` -> `phpcr` to match other Bundles.
* **2013-07-28**: [DependencyInjection] added `enabled` flag to
  `phpcr_provider` config.
* **2013-07-26**: [Model] Removed setRouteContent and getRouteContent, use
  setContent and getContent instead.
* **2013-07-19**: [Model] Separated database agnostic, doctrine generic and
  PHPCR-ODM specific code to prepare for Doctrine ORM support.
* **2013-07-17**: [FormType] Moved TermsFormType to CoreBundle and renamed it
  to CheckboxUrlLableFormType.

1.1.0-beta2
-----------

* **2013-05-28**: [Bundle] Only include Doctrine PHPCR compiler pass if
  PHPCR-ODM is present.
* **2013-05-25**: [Bundle] Drop symfony_ from symfony_cmf prefix.
* **2013-05-24**: [Document] ContentRepository now requires ManagerRegistry in
  the constructor and provides `setManagerName()` in the same way as
  RouteProvider.
* **2013-05-24**: [Document] RouteProvider now requires ManagerRegistry in the
  constructor (the `cmf_routing.default_route_provider` does this for you). To
  use a different document manager from the registry, call `setManagerName()`
  on the RouteProvider.


text:
#include "HLSLParser.h"
#include "HLSLKeywords.h"
#include "Helper.h"
#include "AST.h"
#include "ASTFactory.h"
#include "ReportIdents.h"
#include "Exception.h"

namespace Xsc
{

/*
The HLSL parser is not a fully context free parser,
because cast expressions in HLSL are not context free.
Take a look at the following example:

    int X = 0;
    (X) - (1);

Here "(X) - (1)" is a binary expression, but in the following example it is a cast expression:

    typedef int X;
    (X) - (1);

Here "-(1)" is an unary expression. Thus, cast expression can only be parsed, if the parser is aware of all
types, which are valid in the respective scope.
*/

HLSLParser::HLSLParser(Log* log) :
    SLParser { log }
{
}

ProgramPtr HLSLParser::ParseSource(
    const SourceCodePtr& source, const NameMangling& nameMangling, const InputShaderVersion versionIn, bool rowMajorAlignment, bool enableWarnings)
{
    /* Copy parameters */
    useD3D10Semantics_  = (versionIn >= InputShaderVersion::HLSL4);
    enableCgKeywords_   = (versionIn == InputShaderVersion::Cg);
    rowMajorAlignment_  = rowMajorAlignment;

    EnableWarnings(enableWarnings);

    GetNameMangling() = nameMangling;

    /* Start scanning source code */
    PushScannerSource(source);

    try
    {
        /* Parse program AST */
        auto ast = ParseProgram(source);
        return (GetReportHandler().HasErrors() ? nullptr : ast);
    }
    catch (const Report& err)
    {
        if (GetLog())
            GetLog()->SubmitReport(err);
    }

    return nullptr;
}

/*
 * ======= Private: =======
 */

ScannerPtr HLSLParser::MakeScanner()
{
    return std::make_shared<HLSLScanner>(enableCgKeywords_, GetLog());
}

bool HLSLParser::IsDataType() const
{
    return
    (
        IsBaseDataType() || Is(Tokens::Vector) || Is(Tokens::Matrix) ||
        Is(Tokens::Buffer) || Is(Tokens::Sampler) || Is(Tokens::SamplerState)
    );
}

bool HLSLParser::IsBaseDataType() const
{
    return (Is(Tokens::ScalarType) || Is(Tokens::VectorType) || Is(Tokens::MatrixType) || Is(Tokens::StringType));
}

bool HLSLParser::IsLiteral() const
{
    return (Is(Tokens::NullLiteral) || Is(Tokens::BoolLiteral) || Is(Tokens::IntLiteral) || Is(Tokens::FloatLiteral) || Is(Tokens::StringLiteral));
}

bool HLSLParser::IsArithmeticUnaryExpr() const
{
    return (Is(Tokens::BinaryOp, "-") || Is(Tokens::BinaryOp, "+"));
}

bool HLSLParser::IsModifier() const
{
    return (Is(Tokens::InputModifier) || Is(Tokens::InterpModifier) || Is(Tokens::TypeModifier) || Is(Tokens::StorageClass));
}

TypeSpecifierPtr HLSLParser::MakeTypeSpecifierIfLhsOfCastExpr(const ExprPtr& expr)
{
    /* Type specifier expression (float, int3 etc.) is always allowed for a cast expression */
    if (auto typeSpecifierExpr = expr->As<TypeSpecifierExpr>())
        return typeSpecifierExpr->typeSpecifier;

    /* Is this an object expression? */
    if (auto objectExpr = expr->As<ObjectExpr>())
    {
        /* Check if the identifier refers to a type name */
        if (IsRegisteredTypeName(objectExpr->ident))
        {
            /* Convert the variable access into a type specifier */
            return ASTFactory::MakeTypeSpecifier(std::make_shared<AliasTypeDenoter>(objectExpr->ident));
        }
    }

    /* No type name expression */
    return nullptr;
}

TokenPtr HLSLParser::AcceptIt()
{
    auto tkn = Parser::AcceptIt();

    /* Post-process directives */
    while (Tkn()->Type() == Tokens::Directive)
        ProcessDirective(AcceptIt()->Spell());

    return tkn;
}

void HLSLParser::ProcessDirective(const std::string& ident)
{
    try
    {
        if (ident == "line")
            ProcessDirectiveLine();
        else if (ident == "pragma")
            ProcessDirectivePragma();
        else
            RuntimeErr(R_InvalidHLSLDirectiveAfterPP);
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
}

void HLSLParser::ProcessDirectiveLine()
{
    int lineNo = 0;
    std::string filename;

    /* Parse '#line'-directive with base class "AcceptIt" functions to avoid recursive calls of this function */
    if (Is(Tokens::IntLiteral))
        lineNo = ParseIntLiteral(Parser::AcceptIt());
    else
        ErrorUnexpected(Tokens::IntLiteral);

    if (Is(Tokens::StringLiteral))
        filename = Parser::AcceptIt()->SpellContent();
    else
        filename = GetScanner().Source()->Filename();

    /* Set new line number and filename */
    auto currentLine = static_cast<int>(GetScanner().PreviousToken()->Pos().Row());
    GetScanner().Source()->NextSourceOrigin(filename, (lineNo - currentLine - 1));
}

void HLSLParser::ProcessDirectivePragma()
{
    /* Parse 'pack_matrix' pragma */
    if (Is(Tokens::Ident) && Tkn()->Spell() == "pack_matrix")
    {
        Parser::AcceptIt();

        auto AcceptToken = [&](const Tokens type)
        {
            if (!Is(type))
                RuntimeErr(R_UnexpectedTokenInPackMatrixPragma);

            // PATCH: 'this->' is required here, due to GCC bug:
            // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58972
            return this->Parser::AcceptIt();
        };

        AcceptToken(Tokens::LBracket);
        auto alignmentTkn = AcceptToken(Tokens::TypeModifier);
        AcceptToken(Tokens::RBracket);

        /* Set matrix pack alignment */
        auto alignment = alignmentTkn->Spell();
        if (alignment == "row_major")
            rowMajorAlignment_ = true;
        else if (alignment == "column_major")
            rowMajorAlignment_ = false;
        else
            Error(R_UnknownMatrixPackAlignment(alignment), alignmentTkn.get());
    }
    else
        Error(R_InvalidHLSLPragmaAfterPP);
}

/* ------- Symbol table ------- */

void HLSLParser::OpenScope()
{
    typeNameSymbolTable_.OpenScope();
}

void HLSLParser::CloseScope()
{
    typeNameSymbolTable_.CloseScope();
}

void HLSLParser::RegisterTypeName(const std::string& ident)
{
    typeNameSymbolTable_.Register(ident, true, nullptr, false);
}

bool HLSLParser::IsRegisteredTypeName(const std::string& ident) const
{
    return typeNameSymbolTable_.Fetch(ident);
}

AliasDeclStmntPtr HLSLParser::MakeAndRegisterBuildinAlias(const DataType dataType, const std::string& ident)
{
    auto ast = ASTFactory::MakeBaseTypeAlias(dataType, ident);
    RegisterTypeName(ident);
    ast->flags << AST::isBuiltin;
    return ast;
}

void HLSLParser::GeneratePreDefinedTypeAliases(Program& ast)
{
    static const std::vector<std::pair<DataType, std::string>> preDefinedTypes
    {
        { DataType::Int,          "DWORD"        },
        { DataType::Float,        "FLOAT"        },
        { DataType::Float4,       "VECTOR"       },
        { DataType::Float4x4,     "MATRIX"       },
        { DataType::String,       "STRING"       },
      //{ DataType::Texture,      "TEXTURE"      },
      //{ DataType::PixelShader,  "PIXELSHADER"  },
      //{ DataType::VertexShader, "VERTEXSHADER" },
    };

    for (const auto& type : preDefinedTypes)
    {
        ast.globalStmnts.push_back(
            MakeAndRegisterBuildinAlias(type.first, type.second)
        );
    }
}

TypeSpecifierPtr HLSLParser::MakeTypeSpecifierWithPackAlignment()
{
    auto ast = Make<TypeSpecifier>();

    if (rowMajorAlignment_)
        ast->SetTypeModifier(TypeModifier::RowMajor);

    return ast;
}

/* ------- Parse functions ------- */

ProgramPtr HLSLParser::ParseProgram(const SourceCodePtr& source)
{
    auto ast = Make<Program>();

    OpenScope();

    /* Generate pre-defined typedef-statements */
    GeneratePreDefinedTypeAliases(*ast);

    /* Keep reference to preprocessed source code */
    ast->sourceCode = source;

    while (true)
    {
        /* Ignore all null statements and techniques */
        ParseAndIgnoreTechniquesAndNullStmnts();

        /* Check if end of stream has been reached */
        if (Is(Tokens::EndOfStream))
            break;

        /* Parse next global declaration */
        ParseStmntWithCommentOpt(ast->globalStmnts, std::bind(&HLSLParser::ParseGlobalStmnt, this));
    }

    CloseScope();

    return ast;
}

CodeBlockPtr HLSLParser::ParseCodeBlock()
{
    auto ast = Make<CodeBlock>();

    /* Parse statement list */
    Accept(Tokens::LCurly);
    OpenScope();
    {
        ast->stmnts = ParseLocalStmntList();
    }
    CloseScope();
    Accept(Tokens::RCurly);

    return ast;
}

VarDeclStmntPtr HLSLParser::ParseParameter()
{
    auto ast = Make<VarDeclStmnt>();

    /* Parse parameter as single variable declaration */
    ast->attribs        = ParseAttributeList();
    ast->typeSpecifier  = ParseTypeSpecifier();

    ast->varDecls.push_back(ParseVarDecl(ast.get()));

    /* Mark with 'parameter' flag */
    ast->flags << VarDeclStmnt::isParameter;

    return UpdateSourceArea(ast);
}

StmntPtr HLSLParser::ParseLocalStmnt()
{
    return ParseStmnt(true);
}

StmntPtr HLSLParser::ParseForLoopInitializer()
{
    return ParseStmnt(false);
}

SwitchCasePtr HLSLParser::ParseSwitchCase()
{
    auto ast = Make<SwitchCase>();

    /* Parse switch case header */
    if (Is(Tokens::Case))
    {
        Accept(Tokens::Case);
        ast->expr = ParseExpr();
    }
    else
        Accept(Tokens::Default);
    Accept(Tokens::Colon);

    /* Parse switch case statement list */
    while (!Is(Tokens::Case) && !Is(Tokens::Default) && !Is(Tokens::RCurly))
        ParseStmntWithCommentOpt(ast->stmnts, std::bind(&HLSLParser::ParseStmnt, this, true));

    return ast;
}

VarDeclPtr HLSLParser::ParseVarDecl(VarDeclStmnt* declStmntRef, const TokenPtr& identTkn)
{
    auto ast = Make<VarDecl>();

    /* Store reference to parent node */
    ast->declStmntRef = declStmntRef;

    /* Parse variable declaration */
    ast->ident = ParseIdentWithNamespaceOpt(ast->namespaceExpr, identTkn, &ast->area);

    /* Parse optional array dimension, semantic, and annocations */
    ast->arrayDims = ParseArrayDimensionList(true);

    ParseVarDeclSemantic(*ast);

    ast->annotations = ParseAnnotationList();

    /* Parse optional initializer expression */
    if (Is(Tokens::AssignOp, "="))
        ast->initializer = ParseInitializer();

    return ast;
}

SamplerValuePtr HLSLParser::ParseSamplerValue()
{
    auto ast = Make<SamplerValue>();

    /* Parse state name */
    ast->name = ParseIdent();

    /* Parse value expression */
    Accept(Tokens::AssignOp, "=");
    ast->value = ParseExpr();
    Semi();

    return ast;
}

AttributePtr HLSLParser::ParseAttribute()
{
    Accept(Tokens::LParen);

    auto ast = Make<Attribute>();

    /* Parse attribute type  */
    auto attribIdent = ParseIdent();
    ast->attributeType = HLSLKeywordToAttributeType(attribIdent);

    UpdateSourceArea(ast);

    if (ast->attributeType == AttributeType::Undefined)
        Warning(R_UnknownAttribute(attribIdent));

    /* Parse optional attribute parameters */
    if (Is(Tokens::LBracket))
    {
        AcceptIt();

        if (!Is(Tokens::RBracket))
        {
            while (true)
            {
                ast->arguments.push_back(ParseExpr());
                if (Is(Tokens::Comma))
                    AcceptIt();
                else
                    break;
            }
        }

        Accept(Tokens::RBracket);
    }

    Accept(Tokens::RParen);

    return ast;
}

// https://msdn.microsoft.com/en-us/library/windows/desktop/bb509709#Profiles
static ShaderTarget HLSLShaderProfileToTarget(const std::string& s)
{
    if (s.size() >= 2)
    {
        auto p = s.substr(0, 2);
        if (p == "vs") return ShaderTarget::VertexShader;
        if (p == "hs") return ShaderTarget::TessellationControlShader;
        if (p == "ds") return ShaderTarget::TessellationEvaluationShader;
        if (p == "gs") return ShaderTarget::GeometryShader;
        if (p == "ps") return ShaderTarget::FragmentShader;
        if (p == "cs") return ShaderTarget::ComputeShader;
    }
    return ShaderTarget::Undefined;
}

// ':' 'register' '(' (IDENT ',')? IDENT ('[' INT_LITERAL ']')? ')'
RegisterPtr HLSLParser::ParseRegister(bool parseColon)
{
    /* Colon is only syntactic sugar, thus not part of the source area */
    if (parseColon)
        Accept(Tokens::Colon);

    auto ast = Make<Register>();

    Accept(Tokens::Register);
    Accept(Tokens::LBracket);

    auto typeIdent = ParseIdent();

    /* Parse optional shader profile */
    if (Is(Tokens::Comma))
    {
        ast->shaderTarget = HLSLShaderProfileToTarget(typeIdent);

        //TODO: only report a warning (or rather an error), if all valid profiles are checked correctly
        //if (ast->shaderTarget == ShaderTarget::Undefined)
        //    Warning("unknown shader profile: '" + typeIdent + "'");

        AcceptIt();
        typeIdent = ParseIdent();
    }

    /* Set area offset to register type character */
    ast->area.Offset(GetScanner().PreviousToken()->Pos());

    /* Get register type and slot index from type identifier */
    ast->registerType = CharToRegisterType(typeIdent.front());

    if (typeIdent.size() > 1)
        ast->slot = ParseIntLiteral(typeIdent.substr(1), GetScanner().PreviousToken().get());

    /* Validate register type and slot index */
    if (ast->registerType == RegisterType::Undefined)
        Warning(R_UnknownSlotRegister(typeIdent.substr(0, 1)));

    /* Parse optional sub component (is only added to slot index) */
    if (Is(Tokens::LParen))
    {
        AcceptIt();
        ast->slot += ParseIntLiteral();
        Accept(Tokens::RParen);
    }

    Accept(Tokens::RBracket);

    return UpdateSourceArea(ast);
}

// ':' 'packoffset' '(' IDENT ('.' COMPONENT)? ')'
PackOffsetPtr HLSLParser::ParsePackOffset(bool parseColon)
{
    if (parseColon)
        Accept(Tokens::Colon);

    auto ast = Make<PackOffset>();

    Accept(Tokens::PackOffset);
    Accept(Tokens::LBracket);

    ast->registerName = ParseIdent();

    if (Is(Tokens::Dot))
    {
        AcceptIt();
        ast->vectorComponent = ParseIdent();
    }

    Accept(Tokens::RBracket);

    return UpdateSourceArea(ast);
}

TypeSpecifierPtr HLSLParser::ParseTypeSpecifier(bool parseVoidType)
{
    auto ast = MakeTypeSpecifierWithPackAlignment();

    /* Parse modifiers and primitive types */
    while (IsModifier() || Is(Tokens::PrimitiveType))
        ParseModifiers(ast.get(), true);

    /* Parse variable type denoter with optional struct declaration */
    ast->typeDenoter = ParseTypeDenoterWithStructDeclOpt(ast->structDecl);

    return UpdateSourceArea(ast);
}

BufferDeclPtr HLSLParser::ParseBufferDecl(BufferDeclStmnt* declStmntRef, const TokenPtr& identTkn)
{
    auto ast = Make<BufferDecl>();

    /* Store reference to parent node */
    ast->declStmntRef = declStmntRef;

    /* Parse identifier, optional array dimension list, and optional slot registers */
    ast->ident          = ParseIdent(identTkn);
    ast->arrayDims      = ParseArrayDimensionList();
    ast->slotRegisters  = ParseRegisterList();
    ast->annotations    = ParseAnnotationList();

    return ast;
}

SamplerDeclPtr HLSLParser::ParseSamplerDecl(SamplerDeclStmnt* declStmntRef, const TokenPtr& identTkn)
{
    auto ast = Make<SamplerDecl>();

    /* Store reference to parent node */
    ast->declStmntRef = declStmntRef;

    /* Parse identifier, optional array dimension list, and optional slot registers */
    ast->ident          = ParseIdent(identTkn);
    ast->arrayDims      = ParseArrayDimensionList();
    ast->slotRegisters  = ParseRegisterList();

    /* Parse optional static sampler state (either for D3D9 or D3D10+ shaders) */
    if (Is(Tokens::AssignOp, "="))
    {
        /* Parse sampler state ("sampler_state" in DX9 only) */
        AcceptIt();
        Accept(Tokens::SamplerState, "sampler_state");
        Accept(Tokens::LCurly);

        ast->textureIdent = ParseSamplerStateTextureIdent();
        ast->samplerValues = ParseSamplerValueList();

        Accept(Tokens::RCurly);
    }
    else if (Is(Tokens::LCurly))
    {
        AcceptIt();
        ast->samplerValues = ParseSamplerValueList();
        Accept(Tokens::RCurly);
    }

    return ast;
}

StructDeclPtr HLSLParser::ParseStructDecl(bool parseStructTkn, const TokenPtr& identTkn)
{
    auto tkn = Tkn();
    auto ast = Make<StructDecl>();

    /* Parse structure declaration */
    if (parseStructTkn)
    {
        if (Is(Tokens::Class))
        {
            AcceptIt();
            ast->isClass = true;
        }
        else
            Accept(Tokens::Struct);
        UpdateSourceArea(ast);
    }

    if (Is(Tokens::Ident) || identTkn)
    {
        /* Parse structure name */
        tkn = Tkn();
        ast->ident = (identTkn ? identTkn->Spell() : ParseIdent());
        UpdateSourceArea(ast);

        /* Register type name in symbol table */
        RegisterTypeName(ast->ident);

        /* Parse optional inheritance (not documented in HLSL but supported; only single inheritance) */
        if (Is(Tokens::Colon))
        {
            AcceptIt();

            ast->baseStructName = ParseIdent();
            if (ast->baseStructName == ast->ident)
                Error(R_IllegalRecursiveInheritance);

            if (Is(Tokens::Comma))
                Error(R_IllegalMultipleInheritance, false);
        }
    }

    GetReportHandler().PushContextDesc(ast->ToString());
    {
        /* Parse member variable declarations */
        ast->localStmnts = ParseGlobalStmntList();

        for (auto& stmnt : ast->localStmnts)
        {
            if (stmnt->Type() == AST::Types::VarDeclStmnt)
            {
                /* Store copy in member variable list */
                ast->varMembers.push_back(std::static_pointer_cast<VarDeclStmnt>(stmnt));
            }
            else if (auto basicDeclStmnt = stmnt->As<BasicDeclStmnt>())
            {
                if (basicDeclStmnt->declObject->Type() == AST::Types::FunctionDecl)
                {
                    /* Store copy in member function list */
                    ast->funcMembers.push_back(std::static_pointer_cast<FunctionDecl>(basicDeclStmnt->declObject));
                }
                else
                    Error(R_IllegalDeclStmntInsideDeclOf(ast->ToString()), stmnt->area, false);
            }
            else
                Error(R_IllegalDeclStmntInsideDeclOf(ast->ToString()), stmnt->area, false);
        }

        /* Decorate all member variables with a reference to this structure declaration */
        for (auto& varDeclStmnt : ast->varMembers)
        {
            for (auto& varDecl : varDeclStmnt->varDecls)
                varDecl->structDeclRef = ast.get();
        }

        /* Decorate all member functions with a reference to this structure declaration */
        for (auto& funcDecl : ast->funcMembers)
            funcDecl->structDeclRef = ast.get();
    }
    GetReportHandler().PopContextDesc();

    return ast;
}

AliasDeclPtr HLSLParser::ParseAliasDecl(TypeDenoterPtr typeDenoter)
{
    auto ast = Make<AliasDecl>();

    /* Parse alias identifier */
    ast->ident = ParseIdent();

    /* Register type name in symbol table */
    RegisterTypeName(ast->ident);

    /* Parse optional array dimensions */
    if (Is(Tokens::LParen))
    {
        /* Make array type denoter and use input as sub type denoter */
        typeDenoter = std::make_shared<ArrayTypeDenoter>(typeDenoter, ParseArrayDimensionList());
    }

    /* Store final type denoter in alias declaration */
    ast->typeDenoter = typeDenoter;

    return UpdateSourceArea(ast);
}

FunctionDeclPtr HLSLParser::ParseFunctionDecl(BasicDeclStmnt* declStmntRef, const TypeSpecifierPtr& returnType, const TokenPtr& identTkn)
{
    auto ast = Make<FunctionDecl>();

    /* Store reference to declaration statement parent node */
    ast->declStmntRef = declStmntRef;

    if (returnType)
    {
        /* Take previously parsed return type */
        ast->returnType = returnType;
    }
    else
    {
        /* Parse (and ignore) optional 'inline' keyword */
        if (Is(Tokens::Inline))
            AcceptIt();

        /* Parse return type */
        ast->returnType = ParseTypeSpecifier(true);
    }

    /* Parse function identifier */
    if (identTkn)
    {
        ast->area   = identTkn->Area();
        ast->ident  = identTkn->Spell();
    }
    else
    {
        ast->area   = GetScanner().ActiveToken()->Area();
        ast->ident  = ParseIdent();
    }

    /* Parse parameters */
    ast->parameters = ParseParameterList();

    ParseFunctionDeclSemantic(*ast);

    ast->annotations = ParseAnnotationList();

    /* Parse optional function body */
    if (Is(Tokens::Semicolon))
        AcceptIt();
    else
    {
        GetReportHandler().PushContextDesc(ast->ToString(false));
        {
            ast->codeBlock = ParseCodeBlock();
        }
        GetReportHandler().PopContextDesc();
    }

    return ast;
}

UniformBufferDeclPtr HLSLParser::ParseUniformBufferDecl()
{
    auto ast = Make<UniformBufferDecl>();

    /* Parse buffer header */
    ast->bufferType = ParseUniformBufferType();
    ast->ident      = ParseIdent();

    UpdateSourceArea(ast);

    /* Parse optional registers */
    ast->slotRegisters = ParseRegisterList();

    GetReportHandler().PushContextDesc(ast->ToString());
    {
        /* Parse buffer body */
        ast->localStmnts = ParseGlobalStmntList();

        /* Copy variable declarations into separated list */
        for (auto& stmnt : ast->localStmnts)
        {
            if (stmnt->Type() == AST::Types::VarDeclStmnt)
                ast->varMembers.push_back(std::static_pointer_cast<VarDeclStmnt>(stmnt));
        }

        /* Decorate all member variables with a reference to this buffer declaration */
        for (auto& varDeclStmnt : ast->varMembers)
        {
            for (auto& varDecl : varDeclStmnt->varDecls)
                varDecl->bufferDeclRef = ast.get();
        }

        /* Parse optional semicolon (this seems to be optional for cbuffer, and tbuffer) */
        if (Is(Tokens::Semicolon))
            Semi();
    }
    GetReportHandler().PopContextDesc();

    return ast;
}

/* --- Declaration statements --- */

StmntPtr HLSLParser::ParseGlobalStmnt()
{
    if (Is(Tokens::LParen))
    {
        /* Parse attributes and statement */
        auto attribs = ParseAttributeList();
        auto ast = ParseGlobalStmntPrimary();
        ast->attribs = std::move(attribs);
        return ast;
    }
    else
    {
        /* Parse statement only */
        return ParseGlobalStmntPrimary();
    }
}

StmntPtr HLSLParser::ParseGlobalStmntPrimary()
{
    switch (TknType())
    {
        case Tokens::Sampler:
        case Tokens::SamplerState:
            return ParseGlobalStmntWithSamplerTypeDenoter();
        case Tokens::Buffer:
            return ParseGlobalStmntWithBufferTypeDenoter();
        case Tokens::UniformBuffer:
            return ParseUniformBufferDeclStmnt();
        case Tokens::Typedef:
            return ParseAliasDeclStmnt();
        case Tokens::Void:
        case Tokens::Inline:
            return ParseFunctionDeclStmnt();
        default:
            return ParseGlobalStmntWithTypeSpecifier();
    }
}

StmntPtr HLSLParser::ParseGlobalStmntWithTypeSpecifier()
{
    /* Parse type specifier */
    auto typeSpecifier = ParseTypeSpecifier();

    /* Is this only a struct declaration? */
    if (typeSpecifier->structDecl && Is(Tokens::Semicolon))
    {
        /* Convert type specifier into struct declaration statement */
        auto ast = Make<BasicDeclStmnt>();

        auto structDecl = typeSpecifier->structDecl;
        structDecl->declStmntRef = ast.get();

        ast->declObject = structDecl;

        Semi();

        return ast;
    }

    /* Parse identifier */
    auto identTkn = Accept(Tokens::Ident);

    /* Is this a function declaration? */
    if (Is(Tokens::LBracket))
    {
        /* Parse function declaration statement */
        return ParseFunctionDeclStmnt(typeSpecifier, identTkn);
    }
    else
    {
        /* Parse variable declaration statement */
        auto ast = Make<VarDeclStmnt>();

        ast->typeSpecifier  = typeSpecifier;
        ast->varDecls       = ParseVarDeclList(ast.get(), identTkn);

        Semi();

        return UpdateSourceArea(ast, ast->typeSpecifier.get());
    }
}

StmntPtr HLSLParser::ParseGlobalStmntWithSamplerTypeDenoter()
{
    /* Parse sampler type denoter and identifier */
    auto typeDenoter = ParseSamplerTypeDenoter();
    auto identTkn = Accept(Tokens::Ident);

    if (Is(Tokens::LBracket))
    {
        /* Make variable type from type denoter, then parse function declaration */
        return ParseFunctionDeclStmnt(ASTFactory::MakeTypeSpecifier(typeDenoter), identTkn);
    }
    else
    {
        /* Parse sampler declaration statement with sampler type denoter */
        return ParseSamplerDeclStmnt(typeDenoter, identTkn);
    }
}

StmntPtr HLSLParser::ParseGlobalStmntWithBufferTypeDenoter()
{
    /* Parse buffer type denoter and identifier */
    auto typeDenoter = ParseBufferTypeDenoter();
    auto identTkn = Accept(Tokens::Ident);

    if (Is(Tokens::LBracket))
    {
        /* Make variable type from type denoter, then parse function declaration */
        return ParseFunctionDeclStmnt(ASTFactory::MakeTypeSpecifier(typeDenoter), identTkn);
    }
    else
    {
        /* Parse buffer declaration statement with sampler type denoter */
        return ParseBufferDeclStmnt(typeDenoter, identTkn);
    }
}

BasicDeclStmntPtr HLSLParser::ParseFunctionDeclStmnt(const TypeSpecifierPtr& returnType, const TokenPtr& identTkn)
{
    auto ast = Make<BasicDeclStmnt>();

    if (!returnType)
    {
        /* Parse function attributes */
        ast->attribs = ParseAttributeList();
    }

    /* Parse functoin declaration object */
    ast->declObject = ParseFunctionDecl(ast.get(), returnType, identTkn);

    return ast;
}

BasicDeclStmntPtr HLSLParser::ParseUniformBufferDeclStmnt()
{
    auto ast = Make<BasicDeclStmnt>();

    /* Parse attribute list */
    ast->attribs    = ParseAttributeList();

    /* Parse uniform buffer declaration object */
    auto uniformBufferDecl = ParseUniformBufferDecl();
    ast->declObject = uniformBufferDecl;

    uniformBufferDecl->declStmntRef = ast.get();

    return ast;
}

BufferDeclStmntPtr HLSLParser::ParseBufferDeclStmnt(const BufferTypeDenoterPtr& typeDenoter, const TokenPtr& identTkn)
{
    auto ast = Make<BufferDeclStmnt>();

    ast->typeDenoter = (typeDenoter ? typeDenoter : ParseBufferTypeDenoter());
    ast->bufferDecls = ParseBufferDeclList(ast.get(), identTkn);

    Semi();

    if (identTkn)
        ast->area = identTkn->Area();
    else
        UpdateSourceArea(ast);

    return ast;
}

SamplerDeclStmntPtr HLSLParser::ParseSamplerDeclStmnt(const SamplerTypeDenoterPtr& typeDenoter, const TokenPtr& identTkn)
{
    auto ast = Make<SamplerDeclStmnt>();

    ast->typeDenoter = (typeDenoter ? typeDenoter : ParseSamplerTypeDenoter());
    ast->samplerDecls = ParseSamplerDeclList(ast.get(), identTkn);

    Semi();

    if (identTkn)
        ast->area = identTkn->Area();
    else
        UpdateSourceArea(ast);

    return ast;
}

VarDeclStmntPtr HLSLParser::ParseVarDeclStmnt()
{
    auto ast = Make<VarDeclStmnt>();

    /* Parse type specifier and all variable declarations */
    ast->typeSpecifier  = ParseTypeSpecifier();
    ast->varDecls       = ParseVarDeclList(ast.get());

    Semi();

    return UpdateSourceArea(ast);
}

// 'typedef' type_denoter IDENT;
AliasDeclStmntPtr HLSLParser::ParseAliasDeclStmnt()
{
    auto ast = Make<AliasDeclStmnt>();

    /* Parse type alias declaration */
    Accept(Tokens::Typedef);

    /* Parse type denoter with optional struct declaration */
    auto typeDenoter = ParseTypeDenoterWithStructDeclOpt(ast->structDecl);

    /* Parse type aliases */
    ast->aliasDecls = ParseAliasDeclList(typeDenoter);

    Semi();

    /* Store references in decls to this statement */
    for (auto& decl : ast->aliasDecls)
        decl->declStmntRef = ast.get();

    return UpdateSourceArea(ast);
}

/* --- Statements --- */

StmntPtr HLSLParser::ParseStmnt(bool allowAttributes)
{
    if (allowAttributes)
    {
        /* Parse attributes and statement */
        auto attribs = ParseAttributeList();
        auto ast = ParseStmntPrimary();
        ast->attribs = std::move(attribs);
        return ast;
    }
    else
    {
        /* Check for illegal attributes */
        if (Is(Tokens::LParen))
        {
            /* Print error, but parse and ignore attributes */
            Error(R_NotAllowedInThisContext(R_Attributes), false, false);
            ParseAttributeList();
        }

        /* Parse statement only */
        return ParseStmntPrimary();
    }
}

StmntPtr HLSLParser::ParseStmntPrimary()
{
    /* Determine which kind of statement the next one is */
    switch (TknType())
    {
        case Tokens::Semicolon:
            return ParseNullStmnt();
        case Tokens::LCurly:
            return ParseCodeBlockStmnt();
        case Tokens::Return:
            return ParseReturnStmnt();
        case Tokens::Ident:
            return ParseStmntWithIdent();
        case Tokens::For:
            return ParseForLoopStmnt();
        case Tokens::While:
            return ParseWhileLoopStmnt();
        case Tokens::Do:
            return ParseDoWhileLoopStmnt();
        case Tokens::If:
            return ParseIfStmnt();
        case Tokens::Switch:
            return ParseSwitchStmnt();
        case Tokens::CtrlTransfer:
            return ParseCtrlTransferStmnt();
        case Tokens::Struct:
        case Tokens::Class:
            return ParseStmntWithStructDecl();
        case Tokens::Typedef:
            return ParseAliasDeclStmnt();
        case Tokens::Sampler:
        case Tokens::SamplerState:
            return ParseSamplerDeclStmnt();
        case Tokens::StorageClass:
        case Tokens::InterpModifier:
        case Tokens::TypeModifier:
            return ParseVarDeclStmnt();
        default:
            break;
    }

    if (IsDataType())
        return ParseVarDeclStmnt();

    /* Parse statement of arbitrary expression */
    return ParseExprStmnt();
}

StmntPtr HLSLParser::ParseStmntWithStructDecl()
{
    /* Parse structure declaration statement */
    auto ast = Make<BasicDeclStmnt>();

    auto structDecl = ParseStructDecl();
    structDecl->declStmntRef = ast.get();

    ast->declObject = structDecl;

    if (!Is(Tokens::Semicolon))
    {
        /* Parse variable declaration with previous structure type */
        auto varDeclStmnt = Make<VarDeclStmnt>();

        varDeclStmnt->typeSpecifier = ASTFactory::MakeTypeSpecifier(structDecl);

        /* Parse variable declarations */
        varDeclStmnt->varDecls = ParseVarDeclList(varDeclStmnt.get());
        Semi();

        return UpdateSourceArea(varDeclStmnt);
    }
    else
        Semi();

    return ast;
}

#if 1//TODO: clean this up!!!

// ~~~~~~~~~~~~ MIGHT BE INCOMPLETE ~~~~~~~~~~~~~~~

StmntPtr HLSLParser::ParseStmntWithIdent()
{
    /* Parse the identifier as object expression (can be converted later) */
    auto objectExpr = ParseObjectExpr();

    auto expr = ParseExprWithSuffixOpt(objectExpr);

    if (Is(Tokens::LBracket) || Is(Tokens::UnaryOp) || Is(Tokens::BinaryOp) || Is(Tokens::TernaryOp))
    {
        /* Parse expression statement (function call, variable access, etc.) */
        PushPreParsedAST(expr);
        return ParseExprStmnt();
    }
    else if (Is(Tokens::Semicolon))
    {
        /* Return immediatly with expression statement */
        return ParseExprStmnt(expr);
    }
    else if (Is(Tokens::Comma))
    {
        /* Parse sequence expression */
        return ParseExprStmnt(ParseSequenceExpr(expr));
    }
    else if (expr == objectExpr)
    {
        /* Convert variable identifier to alias type denoter */
        auto ast = Make<VarDeclStmnt>();

        ast->typeSpecifier              = MakeTypeSpecifierWithPackAlignment();
        ast->typeSpecifier->typeDenoter = ParseTypeDenoterWithArrayOpt(ParseAliasTypeDenoter(objectExpr->ident));

        UpdateSourceArea(ast->typeSpecifier, objectExpr.get());

        ast->varDecls = ParseVarDeclList(ast.get());
        Semi();

        return UpdateSourceArea(ast, objectExpr.get());
    }
    else
        return ParseExprStmnt(expr);

    #if 0//DEAD CODE
    ErrorUnexpected(R_ExpectedVarOrAssignOrFuncCall, nullptr, true);

    return nullptr;
    #endif
}

#endif

/* --- Expressions --- */

ExprPtr HLSLParser::ParsePrimaryExpr()
{
    /* Primary prefix of primary expression */
    return ParseExprWithSuffixOpt(ParsePrimaryExprPrefix());
}

ExprPtr HLSLParser::ParsePrimaryExprPrefix()
{
    /* Check if a pre-parsed AST node is available */
    if (auto preParsedAST = PopPreParsedAST())
    {
        if (preParsedAST->Type() == AST::Types::ObjectExpr)
        {
            /* Parse call expression or return pre-parsed object expression */
            auto objectExpr = std::static_pointer_cast<ObjectExpr>(preParsedAST);
            if (Is(Tokens::LBracket))
                return ParseCallExpr(objectExpr);
            else
                return objectExpr;
        }
        else if (preParsedAST->Type() == AST::Types::CallExpr)
        {
            /* Return pre-parsed call expression */
            return std::static_pointer_cast<CallExpr>(preParsedAST);
        }
        else
            ErrorInternal(R_UnexpectedPreParsedAST, __FUNCTION__);
    }

    /* Determine which kind of expression the next one is */
    if (IsLiteral())
        return ParseLiteralExpr();
    if (IsModifier())
        return ParseTypeSpecifierExpr();
    if (IsDataType() || Is(Tokens::Struct))
        return ParseTypeSpecifierOrCallExpr();
    if (Is(Tokens::UnaryOp) || IsArithmeticUnaryExpr())
        return ParseUnaryExpr();
    if (Is(Tokens::LBracket))
        return ParseExprWithBracketPrefix();
    if (Is(Tokens::LCurly))
        return ParseInitializerExpr();
    if (Is(Tokens::Ident))
        return ParseObjectOrCallExpr();

    ErrorUnexpected(R_ExpectedPrimaryExpr, nullptr, true);

    return nullptr;
}

ExprPtr HLSLParser::ParseExprWithSuffixOpt(ExprPtr expr)
{
    /* Parse optional suffix expressions */
    while (true)
    {
        if (Is(Tokens::LParen))
            expr = ParseArrayExpr(expr);
        else if (Is(Tokens::Dot) || Is(Tokens::DColon))
            expr = ParseObjectOrCallExpr(expr);
        else if (Is(Tokens::AssignOp))
            expr = ParseAssignExpr(expr);
        else if (Is(Tokens::UnaryOp))
            expr = ParsePostUnaryExpr(expr);
        else
            break;
    }

    return UpdateSourceArea(expr);
}

LiteralExprPtr HLSLParser::ParseLiteralExpr()
{
    if (!IsLiteral())
        ErrorUnexpected(R_ExpectedLiteralExpr);

    /* Parse literal */
    auto ast = Make<LiteralExpr>();

    if (!Is(Tokens::NullLiteral))
        ast->dataType = TokenToDataType(*Tkn());

    ast->value = AcceptIt()->Spell();

    return UpdateSourceArea(ast);
}

ExprPtr HLSLParser::ParseTypeSpecifierOrCallExpr()
{
    /* Parse type denoter with optional structure delcaration */
    if (!IsDataType() && !Is(Tokens::Struct))
        ErrorUnexpected(R_ExpectedTypeNameOrFuncCall);

    StructDeclPtr structDecl;
    auto typeDenoter = ParseTypeDenoter(true, &structDecl);

    /* Determine which kind of expression this is */
    if (Is(Tokens::LBracket) && !structDecl)
    {
        /* Return function call expression */
        return ParseCallExpr(nullptr, typeDenoter);
    }

    /* Return type name expression */
    auto ast = Make<TypeSpecifierExpr>();
    {
        ast->typeSpecifier               = ASTFactory::MakeTypeSpecifier(typeDenoter);
        ast->typeSpecifier->structDecl   = structDecl;
    }
    UpdateSourceArea(ast->typeSpecifier, structDecl.get());

    return UpdateSourceArea(ast, structDecl.get());
}

TypeSpecifierExprPtr HLSLParser::ParseTypeSpecifierExpr()
{
    auto ast = Make<TypeSpecifierExpr>();

    /* Parse type specifier */
    ast->typeSpecifier = ParseTypeSpecifier();

    return UpdateSourceArea(ast);
}

UnaryExprPtr HLSLParser::ParseUnaryExpr()
{
    if (!Is(Tokens::UnaryOp) && !IsArithmeticUnaryExpr())
        ErrorUnexpected(R_ExpectedUnaryOp);

    /* Parse unary expression (e.g. "++x", "!x", "+x", "-x") */
    auto ast = Make<UnaryExpr>();

    ast->op     = StringToUnaryOp(AcceptIt()->Spell());
    ast->expr   = ParsePrimaryExpr();

    return UpdateSourceArea(ast);
}

PostUnaryExprPtr HLSLParser::ParsePostUnaryExpr(const ExprPtr& expr)
{
    if (!Is(Tokens::UnaryOp))
        ErrorUnexpected(R_ExpectedUnaryOp);

    /* Parse post-unary expression (e.g. "x++", "x--") */
    auto ast = Make<PostUnaryExpr>();

    ast->expr   = expr;
    ast->op     = StringToUnaryOp(AcceptIt()->Spell());

    UpdateSourceArea(ast, expr.get());
    UpdateSourceAreaOffset(ast);

    return ast;
}

ExprPtr HLSLParser::ParseExprWithBracketPrefix()
{
    ExprPtr expr;
    SourceArea area(GetScanner().Pos(), 1);

    /* First parse bracket prefix (bracket: "(EXPR)", cast: "(TYPE)VALUE", call: "(EXPR)(ARGS)") */
    Accept(Tokens::LBracket);
    {
        if (ActiveParsingState().activeTemplate)
        {
            /* Inside brackets, '<' and '>' are allowed as binary operators (albeit an active template is being parsed) */
            auto parsingState = ActiveParsingState();
            parsingState.activeTemplate = false;
            PushParsingState(parsingState);
            {
                expr = ParseExprWithSequenceOpt();
            }
            PopParsingState();
        }
        else
            expr = ParseExprWithSequenceOpt();
    }
    Accept(Tokens::RBracket);

    /*
    Parse cast expression if the expression inside the bracket is the left-hand-side of a cast expression,
    which is checked by the symbol table, because HLSL cast expressions are not context free.
    */
    if (auto typeSpecifier = MakeTypeSpecifierIfLhsOfCastExpr(expr))
    {
        /* Return cast expression */
        auto ast = Make<CastExpr>();

        /* Take type specifier for cast expression */
        ast->area           = area;
        ast->typeSpecifier  = typeSpecifier;

        /* Parse sub expression */
        ast->expr           = ParsePrimaryExpr();

        return UpdateSourceArea(ast);
    }

    /* Parse call expression with a new bracket is following */
    if (Is(Tokens::LBracket))
    {
        if (auto nonBracketExpr = expr->FindFirstNotOf(AST::Types::BracketExpr))
        {
            if (auto objectExpr = nonBracketExpr->As<ObjectExpr>())
            {
                /* Return call expression */
                auto ast = Make<CallExpr>();

                /* Take parameters from previously parsed expression */
                ast->prefixExpr = objectExpr->prefixExpr;
                ast->isStatic   = objectExpr->isStatic;
                ast->ident      = objectExpr->ident;

                /* Parse argument list */
                ast->arguments = ParseArgumentList();

                return UpdateSourceArea(ast);
            }
        }
    }

    /* Return bracket expression */
    auto ast = Make<BracketExpr>();

    ast->area = area;
    ast->expr = expr;

    return UpdateSourceArea(ast);
}

ObjectExprPtr HLSLParser::ParseObjectExpr(const ExprPtr& expr)
{
    /* Parse prefix token if prefix expression is specified  */
    bool isStatic = false;

    if (expr != nullptr)
    {
        /* Parse '::' or '.' prefix */
        if (Is(Tokens::DColon))
        {
            AcceptIt();
            isStatic = true;
        }
        else if (Is(Tokens::Dot))
            AcceptIt();
        else
            ErrorUnexpected(R_ExpectedIdentPrefix);
    }

    auto ast = Make<ObjectExpr>();

    if (expr)
        ast->area = expr->area;

    /* Take sub expression and parse identifier */
    ast->prefixExpr = expr;
    ast->isStatic   = isStatic;
    ast->ident      = ParseIdent();

    return UpdateSourceArea(ast);
}

AssignExprPtr HLSLParser::ParseAssignExpr(const ExprPtr& expr)
{
    auto ast = Make<AssignExpr>();

    /* Take sub expression and parse assignment */
    ast->area       = expr->area;
    ast->lvalueExpr = expr;

    /* Parse assign expression */
    if (Is(Tokens::AssignOp))
    {
        ast->op         = StringToAssignOp(AcceptIt()->Spell());
        UpdateSourceAreaOffset(ast);
        ast->rvalueExpr = ParseExpr();
    }
    else
        ErrorUnexpected(Tokens::AssignOp);

    return UpdateSourceArea(ast);
}

ExprPtr HLSLParser::ParseObjectOrCallExpr(const ExprPtr& expr)
{
    /* Parse variable identifier first (for variables and functions) */
    auto objectExpr = ParseObjectExpr(expr);

    if (Is(Tokens::LBracket))
        return ParseCallExpr(objectExpr);

    return objectExpr;
}

CallExprPtr HLSLParser::ParseCallExpr(const ObjectExprPtr& objectExpr, const TypeDenoterPtr& typeDenoter)
{
    if (objectExpr)
    {
        /* Make new identifier token with source position from input */
        auto identTkn = std::make_shared<Token>(objectExpr->area.Pos(), Tokens::Ident, objectExpr->ident);

        /* Parse call expression and take prefix expression from input */
        return ParseCallExprWithPrefixOpt(objectExpr->prefixExpr, objectExpr->isStatic, identTkn);
    }
    else if (typeDenoter)
    {
        /* Parse call expression with type denoter */
        return ParseCallExprAsTypeCtor(typeDenoter);
    }
    else
    {
        /* Parse completely new call expression */
        return ParseCallExprWithPrefixOpt();
    }
}

CallExprPtr HLSLParser::ParseCallExprWithPrefixOpt(const ExprPtr& prefixExpr, bool isStatic, const TokenPtr& identTkn)
{
    auto ast = Make<CallExpr>();

    /* Take prefix expression */
    ast->prefixExpr = prefixExpr;
    ast->isStatic   = isStatic;

    /* Parse function name */
    if (identTkn)
    {
        /* Take identifier token */
        ast->ident  = identTkn->Spell();
        ast->area   = identTkn->Area();
    }
    else
    {
        /* Parse identifier token */
        ast->ident = ParseIdent();
        UpdateSourceArea(ast);
    }

    /* Parse argument list */
    ast->arguments = ParseArgumentList();

    return UpdateSourceArea(ast);
}

// Parse function call as a type constructor (e.g. "float4(...)")
CallExprPtr HLSLParser::ParseCallExprAsTypeCtor(const TypeDenoterPtr& typeDenoter)
{
    auto ast = Make<CallExpr>();

    /* Take type denoter */
    ast->typeDenoter = typeDenoter;

    /* Parse argument list */
    ast->arguments = ParseArgumentList();

    return UpdateSourceArea(ast);
}

/* --- Lists --- */

std::vector<StmntPtr> HLSLParser::ParseGlobalStmntList()
{
    std::vector<StmntPtr> stmnts;

    Accept(Tokens::LCurly);

    /* Parse all variable declaration statements */
    while (!Is(Tokens::RCurly))
    {
        /* Parse next global declaration (ignore techniques and null statements) */
        ParseAndIgnoreTechniquesAndNullStmnts();
        ParseStmntWithCommentOpt(stmnts, std::bind(&HLSLParser::ParseGlobalStmnt, this));
    }

    AcceptIt();

    return stmnts;
}

std::vector<VarDeclStmntPtr> HLSLParser::ParseAnnotationList()
{
    std::vector<VarDeclStmntPtr> annotations;

    if (Is(Tokens::BinaryOp, "<"))
    {
        AcceptIt();

        while (!Is(Tokens::BinaryOp, ">"))
            annotations.push_back(ParseVarDeclStmnt());

        AcceptIt();
    }

    return annotations;
}

std::vector<RegisterPtr> HLSLParser::ParseRegisterList(bool parseFirstColon)
{
    std::vector<RegisterPtr> registers;

    if (parseFirstColon && Is(Tokens::Register))
        registers.push_back(ParseRegister(false));

    while (Is(Tokens::Colon))
        registers.push_back(ParseRegister());

    return registers;
}

std::vector<AttributePtr> HLSLParser::ParseAttributeList()
{
    std::vector<AttributePtr> attribs;

    while (Is(Tokens::LParen))
        attribs.push_back(ParseAttribute());

    return attribs;
}

std::vector<BufferDeclPtr> HLSLParser::ParseBufferDeclList(BufferDeclStmnt* declStmntRef, const TokenPtr& identTkn)
{
    std::vector<BufferDeclPtr> bufferDecls;

    bufferDecls.push_back(ParseBufferDecl(declStmntRef, identTkn));

    while (Is(Tokens::Comma))
    {
        AcceptIt();
        bufferDecls.push_back(ParseBufferDecl(declStmntRef));
    }

    return bufferDecls;
}

std::vector<SamplerDeclPtr> HLSLParser::ParseSamplerDeclList(SamplerDeclStmnt* declStmntRef, const TokenPtr& identTkn)
{
    std::vector<SamplerDeclPtr> samplerDecls;

    samplerDecls.push_back(ParseSamplerDecl(declStmntRef, identTkn));

    while (Is(Tokens::Comma))
    {
        AcceptIt();
        samplerDecls.push_back(ParseSamplerDecl(declStmntRef));
    }

    return samplerDecls;
}

std::vector<SamplerValuePtr> HLSLParser::ParseSamplerValueList()
{
    std::vector<SamplerValuePtr> samplerValues;

    while (!Is(Tokens::RCurly))
        samplerValues.push_back(ParseSamplerValue());

    return samplerValues;
}

std::vector<AliasDeclPtr> HLSLParser::ParseAliasDeclList(TypeDenoterPtr typeDenoter)
{
    std::vector<AliasDeclPtr> aliasDecls;

    aliasDecls.push_back(ParseAliasDecl(typeDenoter));

    while (Is(Tokens::Comma))
    {
        AcceptIt();
        aliasDecls.push_back(ParseAliasDecl(typeDenoter));
    }

    return aliasDecls;
}

/* --- Others --- */

std::string HLSLParser::ParseIdentWithNamespaceOpt(ObjectExprPtr& namespaceExpr, TokenPtr identTkn, SourceArea* area)
{
    /* Parse first identifier */
    SourceArea identArea;
    auto ident = ParseIdent(identTkn, &identArea);

    /* Check if the current identifier is a static namespace */
    if (Is(Tokens::DColon))
    {
        AcceptIt();

        /* Take first identifier as namespace prefix */
        namespaceExpr           = Make<ObjectExpr>();
        namespaceExpr->ident    = ident;
        namespaceExpr->area     = identArea;

        /* Parse next identifier */
        ObjectExprPtr subObjectExpr;
        ident = ParseIdentWithNamespaceOpt(subObjectExpr, nullptr, area);
        namespaceExpr->prefixExpr = subObjectExpr;

        return ident;
    }

    /* Return identifier and its source area */
    *area = identArea;

    return ident;
}

TypeDenoterPtr HLSLParser::ParseTypeDenoter(bool allowVoidType, StructDeclPtr* structDecl)
{
    if (Is(Tokens::Void))
    {
        /* Parse void type denoter */
        if (allowVoidType)
            return ParseVoidTypeDenoter();

        Error(R_NotAllowedInThisContext(R_VoidTypeDen));
        return nullptr;
    }
    else
    {
        /* Parse primary type denoter and optional array dimensions */
        auto typeDenoter = ParseTypeDenoterPrimary(structDecl);

        if (Is(Tokens::LParen))
        {
            /* Make array type denoter */
            typeDenoter = std::make_shared<ArrayTypeDenoter>(typeDenoter, ParseArrayDimensionList());
        }

        return typeDenoter;
    }
}

TypeDenoterPtr HLSLParser::ParseTypeDenoterPrimary(StructDeclPtr* structDecl)
{
    if (IsBaseDataType())
        return ParseBaseTypeDenoter();
    else if (Is(Tokens::Vector))
        return ParseBaseVectorTypeDenoter();
    else if (Is(Tokens::Matrix))
        return ParseBaseMatrixTypeDenoter();
    else if (Is(Tokens::Ident))
        return ParseAliasTypeDenoter();
    else if (Is(Tokens::Struct))
    {
        if (structDecl)
            return ParseStructTypeDenoterWithStructDeclOpt(*structDecl);
        else
            return ParseStructTypeDenoter();
    }
    else if (Is(Tokens::Buffer))
        return ParseBufferTypeDenoter();
    else if (Is(Tokens::Sampler) || Is(Tokens::SamplerState))
        return ParseSamplerTypeDenoter();

    ErrorUnexpected(R_ExpectedTypeDen, GetScanner().ActiveToken().get(), true);
    return nullptr;
}

TypeDenoterPtr HLSLParser::ParseTypeDenoterWithStructDeclOpt(StructDeclPtr& structDecl, bool allowVoidType)
{
    if (Is(Tokens::Struct) || Is(Tokens::Class))
        return ParseStructTypeDenoterWithStructDeclOpt(structDecl);
    else
        return ParseTypeDenoter(allowVoidType);
}

VoidTypeDenoterPtr HLSLParser::ParseVoidTypeDenoter()
{
    Accept(Tokens::Void);
    return std::make_shared<VoidTypeDenoter>();
}

BaseTypeDenoterPtr HLSLParser::ParseBaseTypeDenoter()
{
    if (IsBaseDataType())
    {
        auto keyword = AcceptIt()->Spell();

        /* Make base type denoter by data type keyword */
        auto typeDenoter = std::make_shared<BaseTypeDenoter>();
        typeDenoter->dataType = ParseDataType(keyword);
        return typeDenoter;
    }
    ErrorUnexpected(R_ExpectedBaseTypeDen, nullptr, true);
    return nullptr;
}

// vector < ScalarType, '1'-'4' >;
BaseTypeDenoterPtr HLSLParser::ParseBaseVectorTypeDenoter()
{
    std::string vectorType;

    /* Parse scalar type */
    Accept(Tokens::Vector);

    if (Is(Tokens::BinaryOp, "<"))
    {
        AcceptIt();

        PushParsingState({ true });
        {
            vectorType = Accept(Tokens::ScalarType)->Spell();

            /* Parse vector dimension */
            Accept(Tokens::Comma);
            int dim = ParseAndEvaluateVectorDimension();

            /* Build final type denoter */
            vectorType += std::to_string(dim);
        }
        PopParsingState();

        Accept(Tokens::BinaryOp, ">");
    }
    else
        vectorType = "float4";

    /* Make base type denoter by data type keyword */
    auto typeDenoter = std::make_shared<BaseTypeDenoter>();
    typeDenoter->dataType = ParseDataType(vectorType);

    return typeDenoter;
}

// matrix < ScalarType, '1'-'4', '1'-'4' >;
BaseTypeDenoterPtr HLSLParser::ParseBaseMatrixTypeDenoter()
{
    std::string matrixType;

    /* Parse scalar type */
    Accept(Tokens::Matrix);

    if (Is(Tokens::BinaryOp, "<"))
    {
        AcceptIt();

        PushParsingState({ true });
        {
            matrixType = Accept(Tokens::ScalarType)->Spell();

            /* Parse matrix dimensions */
            Accept(Tokens::Comma);
            int dimM = ParseAndEvaluateVectorDimension();

            Accept(Tokens::Comma);
            int dimN = ParseAndEvaluateVectorDimension();

            /* Build final type denoter */
            matrixType += std::to_string(dimM) + 'x' + std::to_string(dimN);
        }
        PopParsingState();

        Accept(Tokens::BinaryOp, ">");
    }
    else
        matrixType = "float4x4";

    /* Make base type denoter by data type keyword */
    auto typeDenoter = std::make_shared<BaseTypeDenoter>();
    typeDenoter->dataType = ParseDataType(matrixType);

    return typeDenoter;
}

BufferTypeDenoterPtr HLSLParser::ParseBufferTypeDenoter()
{
    /* Make buffer type denoter */
    auto typeDenoter = std::make_shared<BufferTypeDenoter>();

    /* Parse buffer type */
    auto bufferTypeTkn = Tkn();
    typeDenoter->bufferType = ParseBufferType();

    /* Parse optional template arguments */
    if (Is(Tokens::BinaryOp, "<"))
    {
        PushParsingState({ /*activeTemplate:*/ true });
        {
            AcceptIt();

            /* Parse optional type modifier (only 'snorm' and 'unorm') */
            if (Is(Tokens::TypeModifier))
            {
                //TODO: store this information inside the 'genericTypeDenoter'
                auto modifierStr = Tkn()->Spell();
                auto modifier = ParseTypeModifier();
                if (modifier != TypeModifier::SNorm && modifier != TypeModifier::UNorm)
                    Error(R_InvalidModifierForGenericTypeDen(modifierStr), true, false);
            }

            /* Parse generic type denoter ('<' TYPE '>') */
            typeDenoter->genericTypeDenoter = ParseTypeDenoter(false);

            /* Parse optional generic size */
            if (Is(Tokens::Comma))
            {
                AcceptIt();
                auto genSize = ParseAndEvaluateConstExprInt();

                if (IsTextureMSBufferType(typeDenoter->bufferType))
                {
                    if (genSize < 1 || genSize >= 128)
                        Warning(R_TextureSampleCountLimitIs128(genSize), bufferTypeTkn.get());
                }
                else if (IsPatchBufferType(typeDenoter->bufferType))
                {
                    if (genSize < 1 || genSize > 64)
                        Warning(R_PatchCtrlPointLimitIs64(genSize), bufferTypeTkn.get());
                }
                else
                    Error(R_IllegalBufferTypeGenericSize);

                typeDenoter->genericSize = genSize;
            }

            Accept(Tokens::BinaryOp, ">");
        }
        PopParsingState();
    }

    return typeDenoter;
}

SamplerTypeDenoterPtr HLSLParser::ParseSamplerTypeDenoter()
{
    /* Make sampler type denoter */
    auto samplerType = ParseSamplerType();
    return std::make_shared<SamplerTypeDenoter>(samplerType);
}

StructTypeDenoterPtr HLSLParser::ParseStructTypeDenoter()
{
    /* Parse optional 'struct' keyword */
    if (Is(Tokens::Struct))
        AcceptIt();

    /* Parse identifier */
    auto ident = ParseIdent();

    /* Make struct type denoter */
    auto typeDenoter = std::make_shared<StructTypeDenoter>(ident);

    return typeDenoter;
}

StructTypeDenoterPtr HLSLParser::ParseStructTypeDenoterWithStructDeclOpt(StructDeclPtr& structDecl)
{
    /* Parse 'struct' or 'class' keyword */
    bool isClass = false;

    if (Is(Tokens::Class))
    {
        AcceptIt();
        isClass = true;
    }
    else
        Accept(Tokens::Struct);

    if (Is(Tokens::LCurly))
    {
        /* Parse struct-decl */
        structDecl = ParseStructDecl(false);
        structDecl->isClass = isClass;

        /* Make struct type denoter with reference to the structure of this alias decl */
        return std::make_shared<StructTypeDenoter>(structDecl.get());
    }
    else
    {
        /* Parse struct ident token */
        auto structIdentTkn = Accept(Tokens::Ident);

        if (Is(Tokens::LCurly) || Is(Tokens::Colon))
        {
            /* Parse struct-decl */
            structDecl = ParseStructDecl(false, structIdentTkn);
            structDecl->isClass = isClass;

            /* Make struct type denoter with reference to the structure of this alias decl */
            return std::make_shared<StructTypeDenoter>(structDecl.get());
        }
        else
        {
            /* Make struct type denoter without struct decl */
            return std::make_shared<StructTypeDenoter>(structIdentTkn->Spell());
        }
    }
}

AliasTypeDenoterPtr HLSLParser::ParseAliasTypeDenoter(std::string ident)
{
    /* Parse identifier */
    if (ident.empty())
        ident = ParseIdent();

    /* Make alias type denoter per default (change this to a struct type later) */
    return std::make_shared<AliasTypeDenoter>(ident);
}

void HLSLParser::ParseAndIgnoreTechniquesAndNullStmnts()
{
    /* Ignore all null statements and techniques */
    while (Is(Tokens::Semicolon) || Is(Tokens::Technique))
    {
        if (Is(Tokens::Technique))
            ParseAndIgnoreTechnique();
        else
            AcceptIt();
    }
}

void HLSLParser::ParseAndIgnoreTechnique()
{
    /* Only expect 'technique' keyword */
    Accept(Tokens::Technique);

    Warning(R_TechniquesAreIgnored);

    /* Ignore all tokens until the first opening brace */
    std::stack<TokenPtr> braceTknStack;

    while (!Is(Tokens::LCurly))
        AcceptIt();

    braceTknStack.push(Accept(Tokens::LCurly));

    /* Ignore all tokens and count the opening and closing braces */
    while (!braceTknStack.empty())
    {
        if (Is(Tokens::LCurly))
            braceTknStack.push(Tkn());
        else if (Is(Tokens::RCurly))
            braceTknStack.pop();
        else if (Is(Tokens::EndOfStream))
            Error(R_MissingClosingBrace, braceTknStack.top().get());
        AcceptIt();
    }
}

void HLSLParser::ParseVarDeclSemantic(VarDecl& varDecl, bool allowPackOffset)
{
    while (Is(Tokens::Colon))
    {
        /* Colon is only syntactic sugar, thus not part of the source area */
        Accept(Tokens::Colon);

        if (Is(Tokens::Register))
        {
            /* Parse registers for variable declarations */
            varDecl.slotRegisters.push_back(ParseRegister(false));
        }
        else if (Is(Tokens::PackOffset))
        {
            /* Parse pack offset (ignore previous pack offset) */
            auto packOffset = ParsePackOffset(false);
            if (allowPackOffset)
            {
                if (varDecl.packOffset)
                    Warning(R_PackOffsetOverridden, packOffset->area);
                varDecl.packOffset = packOffset;
            }
            else
                Error(R_IllegalPackOffset, packOffset->area);
        }
        else
        {
            /* Parse semantic (ignore previous semantic) */
            varDecl.semantic = ParseSemantic(false);
        }
    }
}

void HLSLParser::ParseFunctionDeclSemantic(FunctionDecl& funcDecl)
{
    while (Is(Tokens::Colon))
    {
        /* Colon is only syntactic sugar, thus not part of the source area */
        Accept(Tokens::Colon);

        if (Is(Tokens::Register))
        {
            /* Parse and ignore registers for variable declarations */
            Warning(R_RegisterIgnoredForFuncDecls);
            ParseRegister(false);
        }
        else if (Is(Tokens::PackOffset))
        {
            /* Report error and ignore packoffset */
            Error(R_IllegalPackOffset, true);
            ParsePackOffset(false);
        }
        else
        {
            /* Parse semantic (ignore previous semantic) */
            funcDecl.semantic = ParseSemantic(false);
        }
    }
}

DataType HLSLParser::ParseDataType(const std::string& keyword)
{
    try
    {
        if (enableCgKeywords_)
            return HLSLKeywordExtCgToDataType(keyword);
        else
            return HLSLKeywordToDataType(keyword);
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return DataType::Undefined;
}

PrimitiveType HLSLParser::ParsePrimitiveType()
{
    try
    {
        return HLSLKeywordToPrimitiveType(Accept(Tokens::PrimitiveType)->Spell());
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return PrimitiveType::Undefined;
}

InterpModifier HLSLParser::ParseInterpModifier()
{
    try
    {
        return HLSLKeywordToInterpModifier(Accept(Tokens::InterpModifier)->Spell());
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return InterpModifier::Undefined;
}

TypeModifier HLSLParser::ParseTypeModifier()
{
    try
    {
        return HLSLKeywordToTypeModifier(Accept(Tokens::TypeModifier)->Spell());
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return TypeModifier::Undefined;
}

StorageClass HLSLParser::ParseStorageClass()
{
    try
    {
        return HLSLKeywordToStorageClass(Accept(Tokens::StorageClass)->Spell());
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return StorageClass::Undefined;
}

UniformBufferType HLSLParser::ParseUniformBufferType()
{
    try
    {
        return HLSLKeywordToUniformBufferType(Accept(Tokens::UniformBuffer)->Spell());
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return UniformBufferType::Undefined;
}

BufferType HLSLParser::ParseBufferType()
{
    try
    {
        return HLSLKeywordToBufferType(Accept(Tokens::Buffer)->Spell());
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return BufferType::Undefined;
}

SamplerType HLSLParser::ParseSamplerType()
{
    try
    {
        if (Is(Tokens::Sampler) || Is(Tokens::SamplerState))
            return HLSLKeywordToSamplerType(AcceptIt()->Spell());
        else
            ErrorUnexpected(R_ExpectedSamplerOrSamplerState);
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return SamplerType::Undefined;
}

IndexedSemantic HLSLParser::ParseSemantic(bool parseColon)
{
    try
    {
        if (parseColon)
            Accept(Tokens::Colon);
        return HLSLKeywordToSemantic(ParseIdent(), useD3D10Semantics_);
    }
    catch (const std::exception& e)
    {
        Error(e.what());
    }
    return Semantic::UserDefined;
}

std::string HLSLParser::ParseSamplerStateTextureIdent()
{
    std::string ident;

    /* Parse "texture" or "Texture" attribute name */
    if (Is(Tokens::Ident))
        Accept(Tokens::Ident, "Texture");
    else
        Accept(Tokens::Buffer, "texture");

    /* Parse initialization either with standard or angle brackets */
    Accept(Tokens::AssignOp, "=");

    if (Is(Tokens::LBracket))
    {
        AcceptIt();
        ident = ParseIdent();
        Accept(Tokens::RBracket);
    }
    else if (Is(Tokens::BinaryOp, "<"))
    {
        AcceptIt();
        ident = ParseIdent();
        Accept(Tokens::BinaryOp, ">");
    }
    else
        ErrorUnexpected(R_ExpectedOpenBracketOrAngleBracket);

    Semi();

    return ident;
}

bool HLSLParser::ParseModifiers(TypeSpecifier* typeSpecifier, bool allowPrimitiveType)
{
    if (Is(Tokens::InputModifier))
    {
        /* Parse input modifier */
        auto modifier = AcceptIt()->Spell();

        if (modifier == "in")
            typeSpecifier->isInput = true;
        else if (modifier == "out")
            typeSpecifier->isOutput = true;
        else if (modifier == "inout")
        {
            typeSpecifier->isInput = true;
            typeSpecifier->isOutput = true;
        }
        else if (modifier == "uniform")
            typeSpecifier->isUniform = true;
    }
    else if (Is(Tokens::InterpModifier))
    {
        /* Parse interpolation modifier */
        typeSpecifier->interpModifiers.insert(ParseInterpModifier());
    }
    else if (Is(Tokens::TypeModifier))
    {
        /* Parse type modifier (const, row_major, column_major, snorm, unorm) */
        typeSpecifier->SetTypeModifier(ParseTypeModifier());
    }
    else if (Is(Tokens::StorageClass))
    {
        /* Parse storage class */
        typeSpecifier->storageClasses.insert(ParseStorageClass());
    }
    else if (Is(Tokens::PrimitiveType))
    {
        /* Parse primitive type */
        if (!allowPrimitiveType)
            Error(R_NotAllowedInThisContext(R_PrimitiveType), false, false);

        auto primitiveType = ParsePrimitiveType();

        if (typeSpecifier->primitiveType == PrimitiveType::Undefined)
            typeSpecifier->primitiveType = primitiveType;
        else if (typeSpecifier->primitiveType == primitiveType)
            Error(R_DuplicatedPrimitiveType, true, false);
        else if (typeSpecifier->primitiveType != primitiveType)
            Error(R_ConflictingPrimitiveTypes, true, false);
    }
    else
        return false;

    return true;
}

} // /namespace Xsc

// ================================================================================

redpajama_set_name: RedPajamaGithub


text:
<?php
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: google/api/distribution.proto

namespace Google\Api;

use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;

/**
 * Specify a sequence of buckets that all have the same width (except
 * overflow and underflow).  Each bucket represents a constant absolute
 * uncertainty on the specific value in the bucket.
 * Defines `num_finite_buckets + 2` (= N) buckets with these boundaries for
 * bucket `i`:
 *    Upper bound (0 <= i < N-1):     offset + (width * i).
 *    Lower bound (1 <= i < N):       offset + (width * (i - 1)).
 *
 * Generated from protobuf message google.api.Distribution.BucketOptions.Linear
 */
class Distribution_BucketOptions_Linear extends \Google\Protobuf\Internal\Message
{
    /**
     * Must be greater than 0.
     *
     * Generated from protobuf field int32 num_finite_buckets = 1;
     */
    private $num_finite_buckets = 0;
    /**
     * Must be greater than 0.
     *
     * Generated from protobuf field double width = 2;
     */
    private $width = 0.0;
    /**
     * Lower bound of the first bucket.
     *
     * Generated from protobuf field double offset = 3;
     */
    private $offset = 0.0;

    public function __construct() {
        \GPBMetadata\Google\Api\Distribution::initOnce();
        parent::__construct();
    }

    /**
     * Must be greater than 0.
     *
     * Generated from protobuf field int32 num_finite_buckets = 1;
     * @return int
     */
    public function getNumFiniteBuckets()
    {
        return $this->num_finite_buckets;
    }

    /**
     * Must be greater than 0.
     *
     * Generated from protobuf field int32 num_finite_buckets = 1;
     * @param int $var
     * @return $this
     */
    public function setNumFiniteBuckets($var)
    {
        GPBUtil::checkInt32($var);
        $this->num_finite_buckets = $var;

        return $this;
    }

    /**
     * Must be greater than 0.
     *
     * Generated from protobuf field double width = 2;
     * @return float
     */
    public function getWidth()
    {
        return $this->width;
    }

    /**
     * Must be greater than 0.
     *
     * Generated from protobuf field double width = 2;
     * @param float $var
     * @return $this
     */
    public function setWidth($var)
    {
        GPBUtil::checkDouble($var);
        $this->width = $var;

        return $this;
    }

    /**
     * Lower bound of the first bucket.
     *
     * Generated from protobuf field double offset = 3;
     * @return float
     */
    public function getOffset()
    {
        return $this->offset;
    }

    /**
     * Lower bound of the first bucket.
     *
     * Generated from protobuf field double offset = 3;
     * @param float $var
     * @return $this
     */
    public function setOffset($var)
    {
        GPBUtil::checkDouble($var);
        $this->offset = $var;

        return $this;
    }

}


text:
import numpy as np
from os import listdir
from matplotlib import pyplot as plt

def apply_spectrum(data, pca, numinput=256, power=1.0):
    colored = data.dot(np.diag(np.power(pca.sValues[:numinput], power)))
    return colored/colored.std()

def get_params_and_errors(net, toy, nunits=256, folder='.',
                          filestart='toy', ds=1.0):
    filelist = listdir(folder)
    goodfiles = []
    firing_rates = []
    gains = []
    errors = []
    modfit = []
    peaks = []
    peakmodfits = []
    exceptions = []
    for file in filelist:
        dsflag = False
        if 'ds' in file:
            dsflag = file.split('ds')[1].startswith(str(ds))
        if file.endswith('.pickle') and file.startswith(filestart) and dsflag:
            file = folder+file
            try:
                net.load(file)
            except BaseException as ee:
                exceptions.append(file)
                continue
            try:
                fit = np.load(file + 'fit.npy')
            except FileNotFoundError:
                fit = net.modfits
            ok = net.nunits == nunits
            directtest = toy.test_fit(net.Q)
            ok = ok and not (directtest - fit[-1]) > 0.01 and fit[-1] != 0
            if ok:
                modfit.append(fit[-1])
                err = np.mean(net.errorhist[-1000:])
                goodfiles.append(file)
                errors.append(err)
                firing_rates.append(net.p)
                gains.append(net.gain)
                peaks.append(np.min(net.errorhist))
                peakmodfits.append(np.max(fit))
            else:
                exceptions.append(file)
    print('Errors on ', str(len(exceptions)), ' files')
    if len(goodfiles) == 0:
        if len(exceptions) == 0:
            raise FileNotFoundError('No valid files found.')
        raise BaseException(exceptions[0])
    return (goodfiles, firing_rates, gains, errors, peaks, modfit, peakmodfits)

def hp_scatter(firing_rates, gains, modfits, fig=None, ax=None):
    if fig is None:
        fig = plt.figure()
    if ax is None:
        ax = fig.add_subplot(111)
    modfits = [0 if np.isnan(mf) else mf for mf in modfits]
    sc = ax.scatter(firing_rates, gains, c=modfits, cmap='viridis', s=200)
    ax.set_xlabel('Firing rate p')
    ax.set_ylabel('Gain')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlim([np.min(firing_rates)*0.8, np.max(firing_rates)*1.2])
    ax.set_ylim([np.min(gains)*0.8, np.max(gains)*1.2])
    fig.colorbar(sc, ax=ax)

def err_hp_scatter(firing_rates, gains, errors, fig=None, ax=None):
    if fig is None:
        fig = plt.figure()
    if ax is None:
        ax = fig.add_subplot(111)
    goodfr = [firing_rates[ii] for ii in range(len(errors)) if errors[ii] < 1.0]
    goodg = [gains[ii] for ii in range(len(errors)) if errors[ii] < 1.0]
    badfr = [firing_rates[ii] for ii in range(len(errors)) if errors[ii] >= 1.0 or np.isnan(errors[ii])]
    badg = [gains[ii] for ii in range(len(errors)) if errors[ii] >= 1.0 or np.isnan(errors[ii])]
    errors = [er for er in errors if er < 1.0]
    sc = ax.scatter(goodfr, goodg, c=errors, cmap='viridis_r', s=200)
    fig.colorbar(sc, ax=ax)
    ax.set_xlabel('Firing rate p')
    ax.set_ylabel('Gain')
    ax.scatter(badfr, badg, c='r', s=50, marker='x')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlim([np.min(firing_rates)*0.8, np.max(firing_rates)*1.2])
    ax.set_ylim([np.min(gains)*0.8, np.max(gains)*1.2])

def Q_and_svals(Q, pca, ds=1.0, ax=None, errorbars=False):
    if ax is None:
        fig = plt.figure()
        ax = fig.add_subplot(111)
    means = np.abs(Q).mean(0)
    scale = np.max(means)
    means /= scale
    if errorbars:
        stds = np.abs(Q).std(0)/scale
        qline, = ax.errorbar(np.arange(Q.shape[0]), means, yerr=stds, fmt='b.')
    else:
        qline, = ax.plot(np.arange(Q.shape[1]), means, 'b.')
    svals = np.power(pca.sValues[:Q.shape[1]], ds)
    svals /= np.max(svals)
    sline, = ax.plot(svals, 'g')
    # ax.set_title('SAILnet PC usage follows singular values')
    ax.set_xlabel('Singular value rank')
    ax.set_ylabel('Normalized value')
    ax.legend([qline, sline], ['Mean ff weight magnitude', 'Singular value'])

def alt_Q_and_svals(Q, pca, ds=1.0, ax=None):
    if ax is None:
        fig = plt.figure()
        ax = fig.add_subplot(111)
    stds = np.abs(Q).std(0)
    stds /= np.max(stds)
    ax.plot(stds, 'b.')

    svals = np.power(pca.sValues[:256], ds)
    svals /= np.max(svals)
    ax.plot(svals, 'g')

def desphere_results(net, toy, pca_obj, desphere=1.0, folder='Pickles/4oc/'):

    (goodfiles, firing_rates, gains, errors, peaks, modfit,
        peakmodfits) = get_params_and_errors(net, toy, folder=folder, ds=desphere)

    fig = plt.figure()
    fitscat = fig.add_subplot(221)
    hp_scatter(firing_rates, gains, modfit, fig=fig, ax=fitscat)
    fitscat.set_title('Model fits')
    errscat = fig.add_subplot(223)
    err_hp_scatter(firing_rates, gains, errors, fig=fig, ax=errscat)
    errscat.set_title('Mean squared error')

    ind = np.nanargmax(modfit)
    print('Parameters of the best-fitting model: ')
    print('p = ', firing_rates[ind])
    print('gain = ', gains[ind])
    print('mse = ', errors[ind])
    print('model fit = ', modfit[ind])
    winner = goodfiles[ind]
    msewinner = goodfiles[np.nanargmin(errors)]

    try:
        fittrace = net.modfits
    except:
        fittrace = np.load(winner+'fit.npy')
    fitax = fig.add_subplot(222)
    fitax.plot(fittrace)
    fitax.set_xlabel('Training batches')
    fitax.set_ylabel('Model fit')
    # fitax.set_title('Time course of best model recovery')

    net.load(winner)
    Q_and_svals(net.Q, pca_obj, ds=desphere, ax=fig.add_subplot(224))

    fig.tight_layout()

    return winner, msewinner, fig


text:
from __future__ import division, unicode_literals

from re import sub, split
import calendar
import datetime

from django.conf import settings
from django.utils.timezone import now
from django.utils.html import avoid_wrapping
from django.utils.timezone import is_aware, utc
from django.utils.translation import ugettext, ungettext_lazy

def order_by_score(queryset, score_fields, date_field, reverse=True):
    """
    Take some queryset (links or comments) and order them by score,
    which is basically "rating_sum / age_in_seconds ^ scale", where
    scale is a constant that can be used to control how quickly scores
    reduce over time. To perform this in the database, it needs to
    support a POW function, which Postgres and MySQL do. For databases
    that don't such as SQLite, we perform the scoring/sorting in
    memory, which will suffice for development.
    """

    scale = getattr(settings, "SCORE_SCALE_FACTOR", 2)

    # Timestamp SQL function snippets mapped to DB backends.
    # Defining these assumes the SQL functions POW() and NOW()
    # are available for the DB backend.
    timestamp_sqls = {
        "mysql": "UNIX_TIMESTAMP(%s)",
        "postgresql_psycopg2": "EXTRACT(EPOCH FROM %s)" ,
    }
    now_tz_sqls = {
        "mysql": "UTC_TIMESTAMP()",
        "postgresql_psycopg2": "NOW() AT TIME ZONE 'utc'",
    }
    db_engine = settings.DATABASES[queryset.db]["ENGINE"].rsplit(".", 1)[1]
    timestamp_sql = timestamp_sqls.get(db_engine)
    now_sql = now_tz_sqls.get(db_engine) if settings.USE_TZ else "NOW()",

    if timestamp_sql and now_sql:
        score_sql = "(%s) / POW(%s - %s, %s)" % (
            " + ".join(score_fields),
            timestamp_sql % now_sql,
            timestamp_sql % date_field,
            scale,
        )
        order_by = "-score" if reverse else "score"
        return queryset.extra(select={"score": score_sql}).order_by(order_by)
    else:
        for obj in queryset:
            age = (now() - getattr(obj, date_field)).total_seconds()
            score_fields_sum = sum([getattr(obj, f) for f in score_fields])
            score = score_fields_sum / pow(age, scale)
            setattr(obj, "score", score)
        return sorted(queryset, key=lambda obj: obj.score, reverse=reverse)

def auto_tag(link_obj):
    """
    Split's the link object's title into words. Default function for the
    ``AUTO_TAG_FUNCTION`` setting.
    """
    variations = lambda word: [word,
        sub("^([^A-Za-z0-9])*|([^A-Za-z0-9]|s)*$", "", word),
        sub("^([^A-Za-z0-9])*|([^A-Za-z0-9])*$", "", word)]
    return sum(map(variations, split("\s|/", link_obj.title)), [])

TIMESINCE_CHUNKS = (
    (60 * 60 * 24 * 365, ungettext_lazy('%d年', '%d年')),
    (60 * 60 * 24 * 30, ungettext_lazy('%d月', '%d月')),
    (60 * 60 * 24 * 7, ungettext_lazy('%d星期', '%d星期')),
    (60 * 60 * 24, ungettext_lazy('%d天', '%d天')),
    (60 * 60, ungettext_lazy('%d小时', '%d小时')),
    (60, ungettext_lazy('%d分钟', '%d分钟'))
)

def timesince(d, now=None, reversed=False):
    """
    Takes two datetime objects and returns the time between d and now
    as a nicely formatted string, e.g. "10 minutes".  If d occurs after now,
    then "0 minutes" is returned.

    Units used are years, months, weeks, days, hours, and minutes.
    Seconds and microseconds are ignored.  Up to two adjacent units will be
    displayed.  For example, "2 weeks, 3 days" and "1 year, 3 months" are
    possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not.

    Adapted from
    http://web.archive.org/web/20060617175230/http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
    """
    # Convert datetime.date to datetime.datetime for comparison.
    if not isinstance(d, datetime.datetime):
        d = datetime.datetime(d.year, d.month, d.day)
    if now and not isinstance(now, datetime.datetime):
        now = datetime.datetime(now.year, now.month, now.day)

    if not now:
        now = datetime.datetime.now(utc if is_aware(d) else None)

    if reversed:
        d, now = now, d
    delta = now - d

    # Deal with leapyears by subtracing the number of leapdays
    leapdays = calendar.leapdays(d.year, now.year)
    if leapdays != 0:
        if calendar.isleap(d.year):
            leapdays -= 1
        elif calendar.isleap(now.year):
            leapdays += 1
    delta -= datetime.timedelta(leapdays)

    # ignore microseconds
    since = delta.days * 24 * 60 * 60 + delta.seconds
    if since <= 0:
        # d is in the future compared to now, stop processing.
        return avoid_wrapping(ugettext('0 minutes'))
    for i, (seconds, name) in enumerate(TIMESINCE_CHUNKS):
        count = since // seconds
        if count != 0:
            break
    result = avoid_wrapping(name % count)
    if i + 1 < len(TIMESINCE_CHUNKS):
        # Now get the second item
        seconds2, name2 = TIMESINCE_CHUNKS[i + 1]
        count2 = (since - (seconds * count)) // seconds2
        if count2 != 0:
            result += ugettext(', ') + avoid_wrapping(name2 % count2)
    return result

def timeuntil(d, now=None):
    """
    Like timesince, but returns a string measuring the time until
    the given time.
    """
    return timesince(d, now, reversed=True)


text:
//%LICENSE////////////////////////////////////////////////////////////////
//
// Licensed to The Open Group (TOG) under one or more contributor license
// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
// this work for additional information regarding copyright ownership.
// Each contributor licenses this file to you under the OpenPegasus Open
// Source License; you may not use this file except in compliance with the
// License.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////
//
//%/////////////////////////////////////////////////////////////////////////

#ifndef __UNIX_RECORDINLOG_H
#define __UNIX_RECORDINLOG_H

#include "CIM_ClassBase.h"

#include "UNIX_RecordInLogDeps.h"

#define PROPERTY_MESSAGE_LOG				"MessageLog"
#define PROPERTY_LOG_RECORD				"LogRecord"

class UNIX_RecordInLog :
	public CIM_ClassBase
{
public:

	UNIX_RecordInLog();
	~UNIX_RecordInLog();

	virtual Boolean initialize();
	virtual Boolean load(int&);
	virtual Boolean finalize();
	virtual Boolean find(Array<CIMKeyBinding>&);
	virtual Boolean validateKey(CIMKeyBinding&) const;
	virtual void setScope(CIMName);

	virtual Boolean getMessageLog(CIMProperty&) const;
	virtual CIMInstance getMessageLog() const;
	virtual Boolean getLogRecord(CIMProperty&) const;
	virtual CIMInstance getLogRecord() const;

private:
	CIMName currentScope;

#	include "UNIX_RecordInLogPrivate.h"

};

#endif /* UNIX_RECORDINLOG */


text:
package org.springframework.jdbc.object;

import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.Types;

import org.easymock.MockControl;
import org.apache.commons.logging.LogFactory;

import org.springframework.jdbc.AbstractJdbcTests;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * @author Juergen Hoeller
 * @since 22.02.2005
 */
public class BatchSqlUpdateTests extends AbstractJdbcTests {

	private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled();

	public void testBatchUpdateWithExplicitFlush() throws Exception {
		doTestBatchUpdate(false);
	}

	public void testBatchUpdateWithFlushThroughBatchSize() throws Exception {
		doTestBatchUpdate(true);
	}

	private void doTestBatchUpdate(boolean flushThroughBatchSize) throws Exception {
		final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
		final int[] ids = new int[] { 100, 200 };
		final int[] rowsAffected = new int[] { 1, 2 };

		MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
		PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
		mockPreparedStatement.getConnection();
		ctrlPreparedStatement.setReturnValue(mockConnection);
		mockPreparedStatement.setObject(1, new Integer(ids[0]), Types.INTEGER);
		ctrlPreparedStatement.setVoidCallable();
		mockPreparedStatement.addBatch();
		ctrlPreparedStatement.setVoidCallable();
		mockPreparedStatement.setObject(1, new Integer(ids[1]), Types.INTEGER);
		ctrlPreparedStatement.setVoidCallable();
		mockPreparedStatement.addBatch();
		ctrlPreparedStatement.setVoidCallable();
		mockPreparedStatement.executeBatch();
		ctrlPreparedStatement.setReturnValue(rowsAffected);
		if (debugEnabled) {
			mockPreparedStatement.getWarnings();
			ctrlPreparedStatement.setReturnValue(null);
		}
		mockPreparedStatement.close();
		ctrlPreparedStatement.setVoidCallable();

		MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class);
		DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock();
		mockDatabaseMetaData.supportsBatchUpdates();
		ctrlDatabaseMetaData.setReturnValue(true);

		mockConnection.prepareStatement(sql);
		ctrlConnection.setReturnValue(mockPreparedStatement);
		mockConnection.getMetaData();
		ctrlConnection.setReturnValue(mockDatabaseMetaData, 1);

		ctrlPreparedStatement.replay();
		ctrlDatabaseMetaData.replay();
		replay();

		BatchSqlUpdate update = new BatchSqlUpdate(mockDataSource, sql);
		update.declareParameter(new SqlParameter(Types.INTEGER));
		if (flushThroughBatchSize) {
			update.setBatchSize(2);
		}

		update.update(ids[0]);
		update.update(ids[1]);

		if (flushThroughBatchSize) {
			assertEquals(0, update.getQueueCount());
			assertEquals(2, update.getRowsAffected().length);
		}
		else {
			assertEquals(2, update.getQueueCount());
			assertEquals(0, update.getRowsAffected().length);
		}

		int[] actualRowsAffected = update.flush();
		assertEquals(0, update.getQueueCount());

		if (flushThroughBatchSize) {
			assertTrue("flush did not execute updates", actualRowsAffected.length == 0);
		}
		else {
			assertTrue("executed 2 updates", actualRowsAffected.length == 2);
			assertEquals(rowsAffected[0], actualRowsAffected[0]);
			assertEquals(rowsAffected[1], actualRowsAffected[1]);
		}

		actualRowsAffected = update.getRowsAffected();
		assertTrue("executed 2 updates", actualRowsAffected.length == 2);
		assertEquals(rowsAffected[0], actualRowsAffected[0]);
		assertEquals(rowsAffected[1], actualRowsAffected[1]);

		update.reset();
		assertEquals(0, update.getRowsAffected().length);

		ctrlPreparedStatement.verify();
		ctrlDatabaseMetaData.verify();
	}

}


text:
//  Problem Set 1: Time for Change
//  Created by Dulio Denis on 7/4/15.
// ----------------------------------
#include <stdio.h>
#include <math.h>
#include <cs50.h>

int main(void)
{
    int coinsReturned = 0;

    printf("How much change is owed? \n");
    float change = GetFloat();
    // ensure we get a non-negative amount
    while (change < 0) {
        printf("How much change is owed? \n");
        change = GetFloat();
    }

    // round amount to 2 decimals and
    // convert entirely to cents (float -> int)
    int amount =  round(change * 100);

    while (amount > 0) {
        if ((amount - 25) >= 0) { amount = amount - 25; coinsReturned++; }
        else if ((amount - 10) >= 0) { amount = amount - 10; coinsReturned++; }
        else if ((amount - 5) >= 0) { amount = amount - 5; coinsReturned++; }
        else if ((amount - 1) >= 0) { amount = amount - 1; coinsReturned++; }
    }

    printf("%d\n", coinsReturned);
}

/* Output Check:
jharvard@appliance (~/psets): make greedy
clang -ggdb3 -O0 -std=c99 -Wall -Werror    greedy.c  -lcs50 -lm -o greedy
jharvard@appliance (~/psets): ./greedy
How much change is owed?
-0.41
How much change is owed?
-0.41
How much change is owed?
foo
Retry: 0.41
4
jharvard@appliance (~/psets): check50 2014.fall.pset1.greedy greedy.c
:) greedy.c exists
:) greedy.c compiles
:) input of 0.41 yields output of 4
:) input of 0.01 yields output of 1
:) input of 0.15 yields output of 2
:) input of 1.6 yields output of 7
:) input of 23 yields output of 92
:) input of 4.2 yields output of 18
:) rejects a negative input like -.1
:) rejects a non-numeric input of "foo"
:) rejects a non-numeric input of ""
https://sandbox.cs50.net/checks/16a17ee0d9b64a2098dba8ca832d16f9
*/


text:
import $ from 'jquery';
import Vue from 'vue';
import initBlob from '~/blob_edit/blob_bundle';
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import GpgBadges from '~/gpg_badges';
import TreeView from '../../../../tree';
import ShortcutsNavigation from '../../../../shortcuts_navigation';
import BlobViewer from '../../../../blob/viewer';
import NewCommitForm from '../../../../new_commit_form';
import { ajaxGet } from '../../../../lib/utils/common_utils';

document.addEventListener('DOMContentLoaded', () => {
  new ShortcutsNavigation(); // eslint-disable-line no-new
  new TreeView(); // eslint-disable-line no-new
  new BlobViewer(); // eslint-disable-line no-new
  new NewCommitForm($('.js-create-dir-form')); // eslint-disable-line no-new
  $('#tree-slider').waitForImages(() =>
    ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath),
  );

  initBlob();
  const commitPipelineStatusEl = document.querySelector('.js-commit-pipeline-status');
  const statusLink = document.querySelector('.commit-actions .ci-status-link');
  if (statusLink != null) {
    statusLink.remove();
    // eslint-disable-next-line no-new
    new Vue({
      el: commitPipelineStatusEl,
      components: {
        commitPipelineStatus,
      },
      render(createElement) {
        return createElement('commit-pipeline-status', {
          props: {
            endpoint: commitPipelineStatusEl.dataset.endpoint,
          },
        });
      },
    });
  }

  GpgBadges.fetch();
});


text:
package uk.co.rjsoftware.xmpp.model;

import com.google.gson.Gson;

import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class ChatPersistor {

    public static final String CHAT_HISTORY_DIR = "chathistory";

    private final String currentUserId;
    private final String chatJid;
    private final CustomMessageListModel customMessageListModel;
    private final ChatListDataListener listener;
    private final String filename;
    private final Gson gson = new Gson();

    public ChatPersistor(final String currentUserId, final String chatJid, final CustomMessageListModel customMessageListModel) {
        this.currentUserId = currentUserId;
        this.chatJid = chatJid;
        this.customMessageListModel = customMessageListModel;

        this.filename = CHAT_HISTORY_DIR + File.separator + this.currentUserId + File.separator + this.chatJid + ".txt";
        this.listener = new ChatListDataListener(this.customMessageListModel, this.filename);
        this.customMessageListModel.addListDataListener(this.listener);
    }

    private CustomMessage stringToMessage(final String messageString) {
        CustomMessage message = this.gson.fromJson(messageString, CustomMessage.class);
        return message;
    }

    public void readChatHistory() {
        final File historyFile = new File(this.filename);
        if (historyFile.exists()) {
            // read the history from the file system, and update the message list model
            this.customMessageListModel.removeListDataListener(this.listener);

            try {
                final BufferedReader reader = new BufferedReader(new FileReader(historyFile));

                String line = reader.readLine();
                while (null != line) {
                    final CustomMessage message = stringToMessage(line);
                    this.customMessageListModel.add(message);

                    line = reader.readLine();
                }
            } catch (FileNotFoundException exception) {
                throw new RuntimeException(exception);
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            } finally {
                this.customMessageListModel.addListDataListener(this.listener);
            }
        }
    }

    public void writeChatHistory() {
        final File file = new File(this.filename);
        file.getParentFile().mkdirs();

        // read the history from the file system, and update the message list model
        this.customMessageListModel.removeListDataListener(this.listener);
        this.listener.closeFile();

        try {
            final PrintWriter printWriter;
            try {
                printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file, false)));
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            }

            for (CustomMessage message : this.customMessageListModel) {
                printWriter.println(this.gson.toJson(message));
            }

            printWriter.flush();
            printWriter.close();
        } finally {
            this.customMessageListModel.addListDataListener(this.listener);
        }
    }

    private static final class ChatListDataListener implements ListDataListener {

        private final CustomMessageListModel customMessageListModel;
        private final String filename;
        private final Gson gson = new Gson();
        private PrintWriter printWriter;

        private ChatListDataListener(final CustomMessageListModel customMessageListModel, final String filename) {
            this.customMessageListModel = customMessageListModel;
            this.filename = filename;
        }

        private String messageToString(final CustomMessage message) {
            final String messageString = this.gson.toJson(message);
            return messageString;
        }

        private void ensureWriterCreated() {
            if (null != this.printWriter) {
                return;
            }

            final File file = new File(this.filename);
            file.getParentFile().mkdirs();
            try {
                this.printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file, true)));
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            }

        }

        public void closeFile() {
            if (null != this.printWriter) {
                this.printWriter.close();
            }
        }

        @Override
        public void intervalAdded(ListDataEvent event) {
            ensureWriterCreated();
            final CustomMessage message = this.customMessageListModel.get(event.getIndex0());
            this.printWriter.println(messageToString(message));
            this.printWriter.flush();
        }

        @Override
        public void intervalRemoved(ListDataEvent event) {
            // should never happen
        }

        @Override
        public void contentsChanged(ListDataEvent event) {
            // should never happen
        }

        @Override
        protected void finalize() throws Throwable {
            closeFile();
        }

    }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace Blocker.Service
{
    [ServiceContract(Name = "IBlockingService", Namespace = "urn:demos")]
    interface IBlockingServiceAsync
    {
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginNext(AsyncCallback cb, object state);
        int EndNext(IAsyncResult ar);
    }
}


text:
#include "config.h"
#include "LengthPoint.h"

#include "TextStream.h"

namespace WebCore {

TextStream& operator<<(TextStream& ts, const LengthPoint& size)
{
    return ts << size.x() << " " << size.y();
}

} // namespace WebCore