private void EmitVariable(LocalVariableDeclaration variable, CCodeBuilder code)
        {
            Requires.That(nameof(variable), variable.Exists, "tried to look up variable that does not exist");
            var initializer = variable.IsParameter ? $" = {nameMangler.Mangle(variable.Name)}" : "";

            code.AppendLine($"{typeConverter.Convert(variable.Type)} _{NameOf(variable.Reference)}{initializer}; // {variable}");
        }
        public string Convert(DataType type)
        {
            switch (type)
            {
            case VoidType _:
                return("void");

            case SimpleType simpleType:
                return(nameMangler.Mangle(simpleType.Name));

            case ObjectType t:
                return(nameMangler.Mangle(t));

            case PointerType ptr:
                var referenced = ptr.Referent.AssertResolved();
                if (referenced == DataType.Any)
                {
                    return("void*");
                }
                return(Convert(referenced) + "*");

            case FunctionType functionType:
                return($"{Convert(functionType.ReturnType)}(*)({string.Join(", ", functionType.ParameterTypes.Select(Convert))})");

            default:
                throw NonExhaustiveMatchException.For(type);
            }
        }
Пример #3
0
        private void EmitFieldInitialization(FieldInitializationIL fieldInitialization, CCodeBuilder code)
        {
            var fieldName     = nameMangler.Mangle(fieldInitialization.Field);
            var parameterName = nameMangler.Mangle(fieldInitialization.Field.Name);

            // Emit direct access to avoid any issues about whether corresponding variables exist
            code.AppendLine($"_self._self->{fieldName} = {parameterName};");
        }
        public string Convert(ParameterIL parameter)
        {
            var type = typeConverter.Convert(parameter.DataType);

            return(parameter switch
            {
                NamedParameterIL param => $"{type} {nameMangler.Mangle(param.Symbol.Name)}",
                SelfParameterIL _ => $"{type} {nameMangler.SelfName}",
                FieldParameterIL param => $"{type} {nameMangler.Mangle(param.InitializeField.Name)}",
                _ => throw ExhaustiveMatch.Failed(parameter)
            });
Пример #5
0
        public string Convert(Parameter parameter)
        {
            var type = typeConverter.Convert(parameter.Type);
            var name = nameMangler.Mangle(parameter.Name.UnqualifiedName);

            return($"{type} {name}");
        }
Пример #6
0
        public void EmitEntryPointAdapter(FunctionIL entryPoint, Code code)
        {
            if (entryPoint is null)
            {
                return;
            }

            code.Definitions.DeclarationSeparatorLine();
            code.Definitions.AppendLine("// Entry Point Adapter");
            code.Definitions.AppendLine("int32_t main(const int argc, char const * const * const argv)");
            code.Definitions.BeginBlock();
            var arguments = new List <string>();

            foreach (var parameterType in entryPoint.Parameters.Select(p => p.DataType).Cast <ObjectType>())
            {
                if (parameterType.ContainingNamespace == SystemConsole &&
                    parameterType.Name == "Console")
                {
                    code.Definitions.AppendLine(
                        "system__console__Console console = { &system__console__Console___vtable, malloc(sizeof(system__console__Console___Self)) };");
                    arguments.Add("system__console__Console___new__1(console)");
                }
                else if (parameterType.ContainingNamespace == SystemConsole &&
                         parameterType.Name == "Arguments")
                {
                    throw new NotImplementedException();
                }
                else
                {
                    throw new Exception($"Unexpected type for parameter to main: {parameterType}");
                }
            }
            var joinedArguments = string.Join(", ", arguments);

            if (entryPoint.Symbol.ReturnDataType == DataType.Void)
            {
                code.Definitions.AppendLine($"{nameMangler.Mangle(entryPoint.Symbol)}({joinedArguments});");
                code.Definitions.AppendLine("return 0;");
            }
            else
            {
                code.Definitions.AppendLine($"return {nameMangler.Mangle(entryPoint.Symbol)}({joinedArguments})._value;");
            }

            code.Definitions.EndBlock();
        }
        public string Convert(DataType type)
        {
            switch (type)
            {
            default:
                throw new NotImplementedException();

            //throw ExhaustiveMatch.Failed(type);
            case VoidType _:
            case NeverType _:
                return("void");

            case SimpleType simpleType:
                return(nameMangler.Mangle(simpleType.Name));

            case ObjectType t:
                return(nameMangler.Mangle(t));

            //case PointerType ptr:
            //    var referenced = ptr.Referent.AssertKnown();
            //    if (referenced == DataType.Any)
            //        return "void*";
            //    return Convert(referenced) + "*";
            //case FunctionType functionType:
            //    return $"{Convert(functionType.ReturnType)}(*)({string.Join(", ", functionType.ParameterTypes.Select(Convert))})";
            case OptionalType optionalType:
            {
                if (optionalType.Referent is ReferenceType referenceType)
                {
                    return(Convert(referenceType));
                }

                return("_opt__" + Convert(optionalType.Referent));
            }
            }
        }