Ejemplo n.º 1
0
 //Only in effect when extended debug info mode is on.
 private void AddVarPragma(string name, int address, int offset, ElaVariableFlags flags, int data)
 {
     if (debug)
     {
         pdb.AddVarSym(name, address, offset, (Int32)flags, data);
     }
 }
Ejemplo n.º 2
0
        //A main method to add named variables.
        private int AddVariable(string name, ElaExpression exp, ElaVariableFlags flags, int data)
        {
            //Hiding is allowed in parameter list
            if ((flags & ElaVariableFlags.Parameter) == ElaVariableFlags.Parameter)
            {
                CurrentScope.Locals.Remove(name);
            }
            else if (CurrentScope.Locals.ContainsKey(name))
            {
                //But for other cases hiding in the same scope is not allowed
                CurrentScope.Locals.Remove(name);
                AddError(ElaCompilerError.NoHidingSameScope, exp, name.TrimStart('$'));
            }

            CurrentScope.Locals.Add(name, new ScopeVar(flags, currentCounter, data));

            //Additional debug info is only generated when a debug flag is set.
            if (debug && exp != null)
            {
                cw.Emit(Op.Nop);
                AddVarPragma(name, currentCounter, cw.Offset, flags, data);
                AddLinePragma(exp);
            }

            return(AddVariable());
        }
Ejemplo n.º 3
0
 internal Global(string name, ElaVariableFlags flags, int address, int data)
 {
     Name    = name;
     Address = address;
     Data    = data;
     Flags   = flags;
 }
Ejemplo n.º 4
0
        internal void AddFlagsAndData(string name, ElaVariableFlags flags, int data)
        {
            var sv = Locals[name];

            sv           = new ScopeVar(sv.Flags | flags, sv.Address, data);
            Locals[name] = sv;
        }
Ejemplo n.º 5
0
        internal void RemoveFlags(string name, ElaVariableFlags flags)
        {
            var sv = Locals[name];

            sv           = new ScopeVar(sv.Flags ^ flags, sv.Address, sv.Data);
            Locals[name] = sv;
        }
Ejemplo n.º 6
0
 internal Global(string name, ElaVariableFlags flags, int address, int data)
 {
     Name = name;
     Address = address;
     Data = data;
     Flags = flags;
 }
Ejemplo n.º 7
0
 internal ExportVarData(ElaBuiltinKind kind, ElaVariableFlags flags, int data, int moduleHandle, int address)
 {
     Kind = kind;
     ModuleHandle = moduleHandle;
     Address = address;
     Flags = flags;
     Data = data;
 }
Ejemplo n.º 8
0
 internal ExportVarData(ElaBuiltinKind kind, ElaVariableFlags flags, int data, int moduleHandle, int address)
 {
     Kind         = kind;
     ModuleHandle = moduleHandle;
     Address      = address;
     Flags        = flags;
     Data         = data;
 }
Ejemplo n.º 9
0
        //Generic compilation logic for a constructor, compiles both functions and constants.
        //Parameter sca is an address of variable that contains real type ID.
        private void CompileConstructor(string typeName, int sca, ElaExpression exp, ElaVariableFlags flags, int typeModuleId)
        {
            //Constructor name
            var name = String.Empty;

            switch (exp.Type)
            {
            case ElaNodeType.NameReference:
            {
                var n = (ElaNameReference)exp;
                name = n.Name;

                if (!n.Uppercase)
                {
                    AddError(ElaCompilerError.InvalidConstructor, n, FormatNode(n));
                }
                else
                {
                    CompileConstructorConstant(typeName, n, sca, flags, typeModuleId);
                }
            }
            break;

            case ElaNodeType.Juxtaposition:
            {
                var n = (ElaJuxtaposition)exp;

                if (n.Target.Type == ElaNodeType.NameReference)
                {
                    var m = (ElaNameReference)n.Target;
                    name = m.Name;

                    //If a name is uppercase or if this is an infix/postfix/prefix constructor
                    //we assume that this is a correct case and is a constructor function
                    if (m.Uppercase || (Format.IsSymbolic(m.Name) && n.Parameters.Count <= 2))
                    {
                        CompileConstructorFunction(typeName, m.Name, n, sca, flags, typeModuleId);
                        break;
                    }
                }

                AddError(ElaCompilerError.InvalidConstructor, exp, FormatNode(exp));
            }
            break;

            default:
                AddError(ElaCompilerError.InvalidConstructor, exp, FormatNode(exp));
                break;
            }

            //To prevent redundant errors
            CurrentScope.Locals.Remove("$$$$" + name);
            var ab = AddVariable("$$$$" + name, exp, flags | ElaVariableFlags.CompilerGenerated, -1);

            cw.Emit(Op.Ctorid, frame.InternalConstructors.Count - 1);
            PopVar(ab);
        }
Ejemplo n.º 10
0
        //Generic compilation logic for a constructor, compiles both functions and constants.
        //Parameter sca is an address of variable that contains real type ID.
        private void CompileConstructor(string typeName, int sca, ElaExpression exp, ElaVariableFlags flags, int typeModuleId)
        {
            //Constructor name
            var name = String.Empty;

            switch (exp.Type)
            {
                case ElaNodeType.NameReference:
                    {
                        var n = (ElaNameReference)exp;
                        name = n.Name;

                        if (!n.Uppercase)
                            AddError(ElaCompilerError.InvalidConstructor, n, FormatNode(n));
                        else
                            CompileConstructorConstant(typeName, n, sca, flags, typeModuleId);
                    }
                    break;
                case ElaNodeType.Juxtaposition:
                    {
                        var n = (ElaJuxtaposition)exp;

                        if (n.Target.Type == ElaNodeType.NameReference)
                        {
                            var m = (ElaNameReference)n.Target;
                            name = m.Name;

                            //If a name is uppercase or if this is an infix/postfix/prefix constructor
                            //we assume that this is a correct case and is a constructor function
                            if (m.Uppercase || (Format.IsSymbolic(m.Name) && n.Parameters.Count <= 2))
                            {
                                CompileConstructorFunction(typeName, m.Name, n, sca, flags, typeModuleId);
                                break;
                            }
                        }

                        AddError(ElaCompilerError.InvalidConstructor, exp, FormatNode(exp));
                    }
                    break;
                default:
                    AddError(ElaCompilerError.InvalidConstructor, exp, FormatNode(exp));
                    break;
            }

            //To prevent redundant errors
            CurrentScope.Locals.Remove("$$$$" + name);
            var ab = AddVariable("$$$$" + name, exp, flags, -1);
            cw.Emit(Op.Ctorid, frame.InternalConstructors.Count - 1);
            PopVar(ab);
        }
Ejemplo n.º 11
0
        //Compiles a simple parameterless constructor
        private void CompileConstructorConstant(string typeName, ElaNameReference exp, int sca, ElaVariableFlags flags, int typeModuleId)
        {
            frame.InternalConstructors.Add(new ConstructorData
            {
                TypeName = typeName,
                Name = exp.Name,
                Code = -1,
                TypeModuleId = typeModuleId
            });

            AddLinePragma(exp);
            cw.Emit(Op.Ctorid, frame.InternalConstructors.Count - 1);
            PushVar(sca);
            cw.Emit(Op.Newtype0);
            var a = AddVariable(exp.Name, exp, ElaVariableFlags.TypeFun|flags, 0);
            PopVar(a);
        }
Ejemplo n.º 12
0
 private ElaVariableFlags ProcessAttribute(string attribute, ElaVariableFlags flags)
 {
     if (attribute == "private")
     {
         return(flags | ElaVariableFlags.Private);
     }
     else if (attribute == "qualified")
     {
         return(flags | ElaVariableFlags.Qualified);
     }
     else if (attribute == "nowarnings")
     {
         return(flags | ElaVariableFlags.NoWarnings);
     }
     else
     {
         AddError(ElaParserError.UnknownAttribute, attribute);
         return(flags);
     }
 }
Ejemplo n.º 13
0
        //A main method to add named variables.
        private int AddVariable(string name, ElaExpression exp, ElaVariableFlags flags, int data)
        {
            //Hiding is allowed in parameter list
            if ((flags & ElaVariableFlags.Parameter) == ElaVariableFlags.Parameter)
                CurrentScope.Locals.Remove(name);
            else if (CurrentScope.Locals.ContainsKey(name))
            {
                //But for other cases hiding in the same scope is not allowed
                CurrentScope.Locals.Remove(name);
                AddError(ElaCompilerError.NoHindingSameScope, exp, name.TrimStart('$'));
            }

            CurrentScope.Locals.Add(name, new ScopeVar(flags, currentCounter, data));

            //Additional debug info is only generated when a debug flag is set.
            if (debug && exp != null)
            {
                cw.Emit(Op.Nop);
                AddVarPragma(name, currentCounter, cw.Offset, flags, data);
                AddLinePragma(exp);
            }

            return AddVariable();
        }
Ejemplo n.º 14
0
        //Compiles a type constructor
        private void CompileConstructorFunction(string typeName, string name, ElaJuxtaposition juxta, int sca, ElaVariableFlags flags, int typeModuleId)
        {
            Label funSkipLabel;
            int address;
            LabelMap newMap;
            var pars = new List<String>();
            var len = juxta.Parameters.Count;

            AddLinePragma(juxta);
            CompileFunctionProlog(name, len, juxta.Line, juxta.Column, out funSkipLabel, out address, out newMap);

            var sys = new int[len];
            var types = new ScopeVar[len];
            var bangs = new bool[len];

            //Here we have to validate all constructor parameters
            for (var i = 0; i < len; i++)
            {
                var ce = juxta.Parameters[i];
                sys[i] = AddVariable();

                if (bangs[i] = IsBang(ce))
                    cw.Emit(Op.Force);

                PopVar(sys[i]);

                //This can be type a type constraint so we should compile here type check logic
                if (ce.Type == ElaNodeType.Juxtaposition)
                {
                    var jc = (ElaJuxtaposition)ce;

                    //First we check if a constraint is actually valid
                    if (IsInvalidConstructorParameterConstaint(jc))
                        AddError(ElaCompilerError.InvalidConstructorParameter, juxta, FormatNode(ce), name);
                    else if (jc.Target.Type == ElaNodeType.NameReference)
                    {
                        //A simple direct type reference
                        var nt = (ElaNameReference)jc.Target;
                        PushVar(sys[i]);
                        types[i] = TypeCheckConstructor(name, null, nt.Name, nt, false);
                        pars.Add(jc.Parameters[0].GetName());
                    }
                    else if (jc.Target.Type == ElaNodeType.FieldReference)
                    {
                        //A type is qualified with a module alias
                        var fr = (ElaFieldReference)jc.Target;
                        PushVar(sys[i]);
                        types[i] = TypeCheckConstructor(name, fr.TargetObject.GetName(), fr.FieldName, fr, false);
                        pars.Add(jc.Parameters[0].GetName());
                    }
                }
                else if (ce.Type == ElaNodeType.NameReference && !IsInvalidConstructorParameter(ce))
                {
                    pars.Add(ce.GetName());
                    types[i] = ScopeVar.Empty;
                }
                else
                    AddError(ElaCompilerError.InvalidConstructorParameter, juxta, FormatNode(ce), name);
            }

            frame.InternalConstructors.Add(new ConstructorData
            {
                TypeName = typeName,
                Name = name,
                Code = -1,
                Parameters = pars,
                TypeModuleId = typeModuleId
            });

            //For optimization purposes we use a simplified creation algorythm for constructors
            //with 1 and 2 parameters
            if (len == 1)
                PushVar(sys[0]);
            else if (len == 2)
            {
                PushVar(sys[0]);
                PushVar(sys[1]);
            }
            else
            {
                cw.Emit(Op.Newtup, len);

                for (var i = 0; i < len; i++)
                {
                    PushVar(sys[i]);
                    cw.Emit(Op.Tupcons, i);
                }
            }

            var ctid = frame.InternalConstructors.Count - 1;
            cw.Emit(Op.Ctorid, ctid);
            //Refering to captured name, need to recode its address
            PushVar((Byte.MaxValue & sca) + 1 | (sca << 8) >> 8);

            if (len == 1)
                cw.Emit(Op.Newtype1);
            else if (len == 2)
                cw.Emit(Op.Newtype2);
            else
                cw.Emit(Op.Newtype);

            CompileFunctionEpilog(name, len, address, funSkipLabel);
            var a = AddVariable(name, juxta, ElaVariableFlags.TypeFun|ElaVariableFlags.Function|flags, len);
            PopVar(a);

            //We need to add special variable that would indicate that a constructor parameter
            //should be strictly evaluated. Used when inlining constructors. This variable is for
            //metadata only, it is never initialized.
            for (var i = 0; i < bangs.Length; i++)
            {
                if (bangs[i])
                {
                    CurrentScope.Locals.Remove("$-!" + i + name); //To prevent redundant errors
                    AddVariable("$-!" + i + name, juxta, ElaVariableFlags.None, -1);
                }
            }

            //We need to add special variable that would store type check information.
            //This information is used when inlining constructors.
            for (var i = 0; i < types.Length; i++)
            {
                var sv = types[i];

                //There is a type constraint, we have to memoize it for inlining
                if (!sv.IsEmpty())
                {
                    CurrentScope.Locals.Remove("$-" + i + name); //To prevent redundant errors
                    var av = AddVariable("$-" + i + name, juxta, ElaVariableFlags.None, -1);

                    //This ScopeVar was obtained in a different scope, we have to patch it here
                    if ((sv.Flags & ElaVariableFlags.External) == ElaVariableFlags.External)
                        PushVar(sv); //No need to patch an external
                    else
                    {
                        //Roll up one scope
                        sv.Address = ((sv.Address & Byte.MaxValue) - 1) | (sv.Address >> 8) << 8;
                        PushVar(sv);
                    }

                    PopVar(av);
                }
            }

            //To prevent redundant errors
            CurrentScope.Locals.Remove("$-" + name);
            CurrentScope.Locals.Remove("$--" + name);
            //We add special variables that can be used lately to inline this constructor call.
            var consVar = AddVariable("$-" + name, juxta, flags, len);
            var typeVar = AddVariable("$--" + name, juxta, flags, len);
            cw.Emit(Op.Ctorid, ctid);
            PopVar(consVar);
            PushVar(sca);
            PopVar(typeVar);
        }
Ejemplo n.º 15
0
 internal void AddFlagsAndData(string name, ElaVariableFlags flags, int data)
 {
     var sv = Locals[name];
     sv = new ScopeVar(sv.Flags | flags, sv.Address, data);
     Locals[name] = sv;
 }
Ejemplo n.º 16
0
 internal void RemoveFlags(string name, ElaVariableFlags flags)
 {
     var sv = Locals[name];
     sv = new ScopeVar(sv.Flags ^ flags, sv.Address, sv.Data);
     Locals[name] = sv;
 }
Ejemplo n.º 17
0
        //Compiles a type constructor
        private void CompileConstructorFunction(string typeName, string name, ElaJuxtaposition juxta, int sca, ElaVariableFlags flags, int typeModuleId)
        {
            Label    funSkipLabel;
            int      address;
            LabelMap newMap;
            var      pars = new List <String>();
            var      len  = juxta.Parameters.Count;

            AddLinePragma(juxta);
            CompileFunctionProlog(name, len, juxta.Line, juxta.Column, out funSkipLabel, out address, out newMap);

            var sys   = new int[len];
            var types = new ScopeVar[len];
            var bangs = new bool[len];

            //Here we have to validate all constructor parameters
            for (var i = 0; i < len; i++)
            {
                var ce = juxta.Parameters[i];
                sys[i] = AddVariable();

                if (bangs[i] = IsBang(ce))
                {
                    cw.Emit(Op.Force);
                }

                PopVar(sys[i]);

                //This can be type a type constraint so we should compile here type check logic
                if (ce.Type == ElaNodeType.Juxtaposition)
                {
                    var jc = (ElaJuxtaposition)ce;

                    //First we check if a constraint is actually valid
                    if (IsInvalidConstructorParameterConstaint(jc))
                    {
                        AddError(ElaCompilerError.InvalidConstructorParameter, juxta, FormatNode(ce), name);
                    }
                    else if (jc.Target.Type == ElaNodeType.NameReference)
                    {
                        //A simple direct type reference
                        var nt = (ElaNameReference)jc.Target;
                        PushVar(sys[i]);
                        types[i] = TypeCheckConstructor(name, null, nt.Name, nt, false);
                        pars.Add(jc.Parameters[0].GetName());
                    }
                    else if (jc.Target.Type == ElaNodeType.FieldReference)
                    {
                        //A type is qualified with a module alias
                        var fr = (ElaFieldReference)jc.Target;
                        PushVar(sys[i]);
                        types[i] = TypeCheckConstructor(name, fr.TargetObject.GetName(), fr.FieldName, fr, false);
                        pars.Add(jc.Parameters[0].GetName());
                    }
                }
                else if (ce.Type == ElaNodeType.NameReference && !IsInvalidConstructorParameter(ce))
                {
                    pars.Add(ce.GetName());
                    types[i] = ScopeVar.Empty;
                }
                else
                {
                    AddError(ElaCompilerError.InvalidConstructorParameter, juxta, FormatNode(ce), name);
                }
            }

            frame.InternalConstructors.Add(new ConstructorData
            {
                TypeName     = typeName,
                Name         = name,
                Code         = -1,
                Parameters   = pars,
                TypeModuleId = typeModuleId
            });

            //For optimization purposes we use a simplified creation algorythm for constructors
            //with 1 and 2 parameters
            if (len == 1)
            {
                PushVar(sys[0]);
            }
            else if (len == 2)
            {
                PushVar(sys[0]);
                PushVar(sys[1]);
            }
            else
            {
                cw.Emit(Op.Newtup, len);

                for (var i = 0; i < len; i++)
                {
                    PushVar(sys[i]);
                    cw.Emit(Op.Tupcons, i);
                }
            }

            var ctid = frame.InternalConstructors.Count - 1;

            cw.Emit(Op.Ctorid, ctid);
            //Refering to captured name, need to recode its address
            PushVar((Byte.MaxValue & sca) + 1 | (sca << 8) >> 8);

            if (len == 1)
            {
                cw.Emit(Op.Newtype1);
            }
            else if (len == 2)
            {
                cw.Emit(Op.Newtype2);
            }
            else
            {
                cw.Emit(Op.Newtype);
            }

            CompileFunctionEpilog(name, len, address, funSkipLabel);
            var a = AddVariable(name, juxta, ElaVariableFlags.TypeFun | ElaVariableFlags.Function | flags, len);

            PopVar(a);

            //We need to add special variable that would indicate that a constructor parameter
            //should be strictly evaluated. Used when inlining constructors. This variable is for
            //metadata only, it is never initialized.
            for (var i = 0; i < bangs.Length; i++)
            {
                if (bangs[i])
                {
                    CurrentScope.Locals.Remove("$-!" + i + name); //To prevent redundant errors
                    AddVariable("$-!" + i + name, juxta, ElaVariableFlags.CompilerGenerated, -1);
                }
            }

            //We need to add special variable that would store type check information.
            //This information is used when inlining constructors.
            for (var i = 0; i < types.Length; i++)
            {
                var sv = types[i];

                //There is a type constraint, we have to memoize it for inlining
                if (!sv.IsEmpty())
                {
                    CurrentScope.Locals.Remove("$-" + i + name); //To prevent redundant errors
                    var av = AddVariable("$-" + i + name, juxta, ElaVariableFlags.CompilerGenerated, -1);

                    //This ScopeVar was obtained in a different scope, we have to patch it here
                    if ((sv.Flags & ElaVariableFlags.External) == ElaVariableFlags.External)
                    {
                        PushVar(sv); //No need to patch an external
                    }
                    else
                    {
                        //Roll up one scope
                        sv.Address = ((sv.Address & Byte.MaxValue) - 1) | (sv.Address >> 8) << 8;
                        PushVar(sv);
                    }

                    PopVar(av);
                }
            }

            //To prevent redundant errors
            CurrentScope.Locals.Remove("$-" + name);
            CurrentScope.Locals.Remove("$--" + name);
            //We add special variables that can be used lately to inline this constructor call.
            var consVar = AddVariable("$-" + name, juxta, flags | ElaVariableFlags.CompilerGenerated, len);
            var typeVar = AddVariable("$--" + name, juxta, flags | ElaVariableFlags.CompilerGenerated, len);

            cw.Emit(Op.Ctorid, ctid);
            PopVar(consVar);
            PushVar(sca);
            PopVar(typeVar);
        }
Ejemplo n.º 18
0
 //Only in effect when extended debug info mode is on.
 private void AddVarPragma(string name, int address, int offset, ElaVariableFlags flags, int data)
 {
     if (debug)
         pdb.AddVarSym(name, address, offset, (Int32)flags, data);
 }
Ejemplo n.º 19
0
 public void AddVariable(string name, ElaBuiltinKind kind, ElaVariableFlags flags, int data, int moduleHandle, int address)
 {
     variables.Remove(name);
     variables.Add(name, new ExportVarData(kind, flags, data, moduleHandle, address));
 }
Ejemplo n.º 20
0
 internal ScopeVar(ElaVariableFlags flags, int address, int data)
 {
     Address = address;
     Flags   = flags;
     Data    = data;
 }
Ejemplo n.º 21
0
        //Compiles a simple parameterless constructor
        private void CompileConstructorConstant(string typeName, ElaNameReference exp, int sca, ElaVariableFlags flags, int typeModuleId)
        {
            frame.InternalConstructors.Add(new ConstructorData
            {
                TypeName     = typeName,
                Name         = exp.Name,
                Code         = -1,
                TypeModuleId = typeModuleId
            });

            AddLinePragma(exp);
            cw.Emit(Op.Ctorid, frame.InternalConstructors.Count - 1);
            PushVar(sca);
            cw.Emit(Op.Newtype0);
            var a = AddVariable(exp.Name, exp, ElaVariableFlags.TypeFun | flags, 0);

            PopVar(a);
        }
Ejemplo n.º 22
0
 private ElaVariableFlags ProcessAttribute(string attribute, ElaVariableFlags flags)
 {
     if (attribute == "private")
         return flags | ElaVariableFlags.Private;
     else if (attribute == "qualified")
         return flags | ElaVariableFlags.Qualified;
     else
     {
         AddError(ElaParserError.UnknownAttribute, attribute);
         return flags;
     }
 }
Ejemplo n.º 23
0
 public void AddVariable(string name, ElaBuiltinKind kind, ElaVariableFlags flags, int data, int moduleHandle, int address)
 {
     variables.Remove(name);
     variables.Add(name, new ExportVarData(kind, flags, data, moduleHandle, address));
 }