Exemplo n.º 1
0
        private static void CompileStringFromSlice(FunctionCompiler compiler, FunctionalNode stringFromSliceNode)
        {
            VariableReference input  = stringFromSliceNode.InputTerminals[0].GetTrueVariable(),
                              output = stringFromSliceNode.OutputTerminals[1].GetTrueVariable();

            Action <FunctionCompiler> loadStringOutputAllocationReference = c => c.LoadLocalAllocationReference(output);

            // Get a pointer to a heap allocation big enough for the string
            compiler.LoadConstantOffsetFromPointer(loadStringOutputAllocationReference, 0);
            compiler.LoadStringSliceReferenceSizeReference(input);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitAlloc_TEMP();
            compiler._builder.EmitStorePointer();

            // Copy the data from the string slice to the heap allocation
            compiler.LoadStringSliceReferencePointer(input);
            compiler._builder.EmitDerefPointer();
            compiler.LoadConstantOffsetFromPointer(loadStringOutputAllocationReference, 0);
            compiler._builder.EmitDerefPointer();
            compiler.LoadStringSliceReferenceSizeReference(input);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitCopyBytes_TEMP();

            // Copy actual size into string handle
            compiler.LoadConstantOffsetFromPointer(loadStringOutputAllocationReference, TargetConstants.PointerSize);
            compiler.LoadStringSliceReferenceSizeReference(input);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitStoreInteger();
        }
Exemplo n.º 2
0
        private static void CompileOutput(FunctionCompiler compiler, FunctionalNode outputNode)
        {
            VariableReference input        = outputNode.InputTerminals.ElementAt(0).GetTrueVariable();
            NIType            referentType = input.Type.GetReferentType();

            if (referentType.IsInt32())
            {
                compiler.LoadValueAsReference(input);
                compiler._builder.EmitDerefInteger();
                compiler._builder.EmitOutput_TEMP();
            }
            else if (referentType.IsString())
            {
                compiler.LoadValueAsReference(input);
                compiler._builder.EmitDerefPointer();
                compiler.LoadValueAsReference(input);
                compiler._builder.EmitLoadIntegerImmediate(TargetConstants.PointerSize);
                compiler._builder.EmitAdd();
                compiler._builder.EmitDerefInteger();
                compiler._builder.EmitOutputString_TEMP();
            }
            else if (referentType == DataTypes.StringSliceType)
            {
                compiler.LoadStringSliceReferencePointer(input);
                compiler._builder.EmitDerefPointer();
                compiler.LoadStringSliceReferenceSizeReference(input);
                compiler._builder.EmitDerefInteger();
                compiler._builder.EmitOutputString_TEMP();
            }
            else
            {
                throw new NotImplementedException($"Don't know how to display type {referentType} yet.");
            }
        }
Exemplo n.º 3
0
        private static void CompileStringAppend(FunctionCompiler compiler, FunctionalNode stringAppendNode)
        {
            VariableReference stringInput = stringAppendNode.InputTerminals[0].GetTrueVariable(),
                              sliceInput  = stringAppendNode.InputTerminals[1].GetTrueVariable();

            Action <FunctionCompiler> loadStringInputReference = c => c.LoadValueAsReference(stringInput);

            // for now, always create a new allocation, rather than trying to use existing one
            // TODO: free the old allocation
            // compute and store the size first to use it later
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, TargetConstants.PointerSize);
            compiler._builder.EmitDerefInteger();
            compiler.LoadStringSliceReferenceSizeReference(sliceInput);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitAdd();
            compiler._builder.EmitDuplicate();
            compiler._builder.EmitAlloc_TEMP();
            compiler._builder.EmitDuplicate();

            // copy from old allocation to new allocation, then overwrite old allocation pointer
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, 0);
            compiler._builder.EmitDerefPointer();
            compiler._builder.EmitSwap();
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, TargetConstants.PointerSize);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitCopyBytes_TEMP();
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, 0);
            compiler._builder.EmitSwap();
            compiler._builder.EmitStorePointer();

            // copy from slice to offset in new allocation
            compiler.LoadStringSliceReferencePointer(sliceInput);
            compiler._builder.EmitDerefPointer();
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, 0);
            compiler._builder.EmitDerefPointer();
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, TargetConstants.PointerSize);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitAdd();
            compiler.LoadStringSliceReferenceSizeReference(sliceInput);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitCopyBytes_TEMP();

            // copy total size to string
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, TargetConstants.PointerSize);
            compiler._builder.EmitSwap();
            compiler._builder.EmitStoreInteger();
        }
Exemplo n.º 4
0
        private static void CompileStringConcat(FunctionCompiler compiler, FunctionalNode stringConcatNode)
        {
            VariableReference input1 = stringConcatNode.InputTerminals[0].GetTrueVariable(),
                              input2 = stringConcatNode.InputTerminals[1].GetTrueVariable(),
                              output = stringConcatNode.OutputTerminals[2].GetTrueVariable();

            Action <FunctionCompiler> loadStringOutputAllocationReference = c => c.LoadLocalAllocationReference(output);

            // compute and store the size first to use it later
            compiler.LoadConstantOffsetFromPointer(loadStringOutputAllocationReference, TargetConstants.PointerSize);
            compiler.LoadStringSliceReferenceSizeReference(input1);
            compiler._builder.EmitDerefInteger();
            compiler.LoadStringSliceReferenceSizeReference(input2);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitAdd();
            compiler._builder.EmitStoreInteger();

            // allocate a new string with stored size
            compiler.LoadConstantOffsetFromPointer(loadStringOutputAllocationReference, 0);
            compiler.LoadConstantOffsetFromPointer(loadStringOutputAllocationReference, TargetConstants.PointerSize);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitAlloc_TEMP();
            compiler._builder.EmitStorePointer();

            // copy data from both slices
            compiler.LoadStringSliceReferencePointer(input1);
            compiler._builder.EmitDerefPointer();
            compiler.LoadConstantOffsetFromPointer(loadStringOutputAllocationReference, 0);
            compiler._builder.EmitDerefPointer();
            compiler.LoadStringSliceReferenceSizeReference(input1);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitCopyBytes_TEMP();

            compiler.LoadStringSliceReferencePointer(input2);
            compiler._builder.EmitDerefPointer();
            compiler.LoadConstantOffsetFromPointer(loadStringOutputAllocationReference, 0);
            compiler._builder.EmitDerefPointer();
            compiler.LoadStringSliceReferenceSizeReference(input1);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitAdd();
            compiler.LoadStringSliceReferenceSizeReference(input2);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitCopyBytes_TEMP();
        }
Exemplo n.º 5
0
        private static void CompileStringToSlice(FunctionCompiler compiler, FunctionalNode stringToSliceNode)
        {
            VariableReference input  = stringToSliceNode.InputTerminals[0].GetTrueVariable(),
                              output = stringToSliceNode.OutputTerminals[0].GetTrueVariable();

            Action <FunctionCompiler> loadStringInputReference = c => c.LoadValueAsReference(input);

            compiler.LoadStringSliceReferencePointer(output);
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, 0);
            compiler._builder.EmitDerefPointer();
            compiler._builder.EmitStorePointer();

            compiler.LoadStringSliceReferenceSizeReference(output);
            compiler.LoadConstantOffsetFromPointer(loadStringInputReference, TargetConstants.PointerSize);
            compiler._builder.EmitDerefInteger();
            compiler._builder.EmitStoreInteger();
        }