public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType valueType = value.Type;

            if (valueType == ASTType.I8) // no conversion needed.
            {
                return(value);
            }
            IRVariable retVar = tr.Context.AllocateVRegister(ASTType.I8);

            switch (valueType)
            {
            case ASTType.I4:
                tr.Instructions.Add(new IRInstruction(IROpCode.SX, retVar, value));
                break;

            case ASTType.Ptr:
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value));
                break;

            case ASTType.R4:
            case ASTType.R8:
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, retVar, value));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
        public override string VisitASTType(ASTType astType)
        {
            var extensions     = astType.Extensions.Select(e => $"{astType.Name} --|> {e}");
            var fields         = astType.Fields.Select(f => $@"{f.Name}: {string.Join(" ", f.Type.Select(t => t.Value))}").ToList();
            var typeReferences = astType.Fields.Select(f =>
            {
                var _type = f.Type.Last().Value;
                if (_type != "String" && _type != "Number")
                {
                    return($@"{astType.Name} --* {_type}");
                }
                else
                {
                    return("");
                }
            });
            string template = $@"
class {astType.Name} {{
{string.Join("\n", fields)}
}}
{string.Join("\n", extensions)}
{string.Join("\n", typeReferences)}
";

            this.Parts.Add(template);

            return(template);
        }
        /// <summary>
        /// Resolve the imports of this module. Here we'll
        /// link multiple files together. This is not part
        /// of the compiler, but part of the project system.
        /// TODO: verify this approach!
        /// </summary>
        private void ResolveImports()
        {
            this.Imports = new List <IASTNode>();
            var imports = Generator.AST.FindAll(n => n is ASTImport).ToList();

            imports.ForEach(node =>
            {
                ASTImport import = (ASTImport)node;
                var ast          = this.Project.GetAstForModule(import.Name);
                if (!import.Imports.Any())
                {
                    var copies = ast
                                 .FindAll(a => a is ASTType || a is ASTAlias || a is ASTData || a is ASTChoice)
                                 .Select(a => {
                        return(a switch
                        {
                            ASTType t => ObjectCopier.Clone(t) as IASTNode,
                            ASTAlias t => ObjectCopier.Clone(t) as IASTNode,
                            ASTData t => ObjectCopier.Clone(t) as IASTNode,
                            ASTChoice t => ObjectCopier.Clone(t) as IASTNode,
                            _ => throw new Exception("Can only serialize real AST nodes.")
                        });
                    })
                                 .ToList();
                    this.Imports.AddRange(copies);
                }
Exemple #4
0
        public override string VisitASTType(ASTType astType)
        {
            var typeDescription = $@"From module: <a href=""/index.html?path=preview&module={astType.Module}"" target='_parent'>{astType.Module}</a>
{string.Join(" ", astType.Annotations.Select(a => a.Value).ToList()).Trim()}";

            return($@"
<div class=""table-container"">
<table>
    <thead>
        <tr>
            <th colspan=""5"">{astType.Name}</th>
        </tr>
        <tr class=""description"">
            <th colspan=""5"">{typeDescription}</th>
        </tr>
        <tr>
            <th>Name</th>
            <th>Type</th>
            <th>Required</th>
            <th>Restrictions</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        {String.Join(Environment.NewLine, astType.Fields.Select(Visit).ToList())}
    <tbody>
</table>
</div>
");
        }
Exemple #5
0
        public void BasicParserTest()
        {
            var code      = @"
type Person =
    @ The First Name of the Person
    FirstName: String;
";
            var tokens    = new Lexer().Lex(code);
            var parseTree = new Parser(tokens).Parse();

            Assert.NotNull(parseTree);

            List <IASTNode> list = parseTree.ToList();

            Assert.Single(list);

            ASTType t = list[0] as ASTType;

            Assert.Equal("Person", t.Name);
            Assert.Empty(t.Parameters);
            Assert.Single(t.Fields);


            ASTTypeField field = t.Fields.First();

            Assert.Single(field.Annotations);
            Assert.True(field.Annotations.First() is ASTAnnotation);
            Assert.Equal("The First Name of the Person", field.Annotations.First().Value);

            Assert.Equal("FirstName", field.Name);
            Assert.Equal(Helpers.ToTypeDefinition(new [] { "String" }), field.Type);
        }
Exemple #6
0
        public override XmlSchemaObject VisitASTType(ASTType astType)
        {
            var t = new XmlSchemaComplexType
            {
                Name = astType.Name
            };

            var fields = astType.Fields.Select(Visit);
            var all    = new XmlSchemaAll();

            foreach (var field in fields)
            {
                all.Items.Add(field);
            }

            t.Particle = all;

            var description      = string.Join(" ", astType.Annotations.Select(a => a.Value));
            var schemaAnnotation = new XmlSchemaAnnotation();
            var docs             = new XmlSchemaDocumentation()
            {
                Markup = TextToNodeArray(description)
            };

            schemaAnnotation.Items.Add(docs);
            t.Annotation = schemaAnnotation;

            this.Schema.Items.Add(t);

            ExtractElement(astType);

            return(t);
        }
Exemple #7
0
        public void FieldRestrictionsAnnotations()
        {
            var code      = @"
type Person =
    FirstName: String
        & min 2

        @ Should not be 30
        & max 30
    ;
";
            var tokens    = new Lexer().Lex(code);
            var parseTree = new Parser(tokens).Parse().ToList();

            Assert.NotNull(parseTree);

            Assert.Single(parseTree);
            ASTType t = (ASTType)parseTree[0];

            Assert.Single(t.Fields);
            Assert.Equal(2, t.Fields.First().Restrictions.Count());

            ASTTypeField field = t.Fields.First();

            Assert.Equal(2, field.Restrictions.Count());
            Assert.Equal("Should not be 30", field.Restrictions.ToList()[1].Annotations.First().Value);
        }
Exemple #8
0
        public void MultipleTypes()
        {
            var code      = @"
type Person =
    @ The First Name of the Person
    @ A second Annotation is always cool to add
    FirstName: String;
    LastName: String;
    @ Age as a number is weird ofc!
    Age: Number;
    Addresses: List;
type Address =
    Street: String;
    HouseNumber: Number;
";
            var tokens    = new Lexer().Lex(code);
            var parseTree = new Parser(tokens).Parse().ToList();

            Assert.NotNull(parseTree);

            Assert.Equal(2, parseTree.Count());

            ASTType personType = parseTree[0] as ASTType;

            Assert.Equal("Person", personType.Name);

            ASTType addressType = parseTree[1] as ASTType;

            Assert.Equal("Address", addressType.Name);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType    valueType = value.Type;
            IRVariable retVar    = tr.Context.AllocateVRegister(ASTType.I4);

            retVar.RawType = tr.Context.Method.Module.CorLibTypes.Byte;
            switch (valueType)
            {
            case ASTType.I4:
            case ASTType.I8:
            case ASTType.Ptr:
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value));
                break;

            case ASTType.R4:
            case ASTType.R8:
                IRVariable tmp = tr.Context.AllocateVRegister(ASTType.I8);
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmp, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, tmp));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
Exemple #10
0
        public override string VisitASTType(ASTType astType)
        {
            return($@"
<div class=""table-container"">
<table>
    <thead>
        <tr>
            <th colspan=""4"">{astType.Name}</th>
        </tr>
        <tr class=""description"">
            <th colspan=""4"">{string.Join(" ", astType.Annotations.Select(a => a.Value).ToList())}</th>
        </tr>
        <tr>
            <th>Name</th>
            <th>Type</th>
            <th>Required</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        {string.Join("\n", astType.Fields.Select(Visit).ToList())}
    <tbody>
</table>
</div>
");
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType    valueType = value.Type;
            IRVariable retVar    = tr.Context.AllocateVRegister(ASTType.R8);

            switch (valueType)
            {
            case ASTType.I4:
                IRVariable tmpVar = tr.Context.AllocateVRegister(ASTType.I8);
                tr.Instructions.Add(new IRInstruction(IROpCode.SX, tmpVar, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.__SETF)
                {
                    Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.FCONV, retVar, tmpVar));
                break;

            case ASTType.I8:
                tr.Instructions.Add(new IRInstruction(IROpCode.__SETF)
                {
                    Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.FCONV, retVar, value));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
        public override IEnumerable <Descriptor> VisitASTType(ASTType astType)
        {
            yield return(new Descriptor($"{astType.Name}")
            {
                Module = ModuleName,
                Name = astType.Name,
                Description = MapAnnotations(astType.Annotations),
                DescriptorType = DescriptorType.Type.ToString("g")
            });


            foreach (var field in astType.Fields)
            {
                if (field.Module == ModuleName)
                {
                    yield return(new Descriptor(field.Name)
                    {
                        Module = ModuleName,
                        Name = field.Name,
                        Description = MapAnnotations(field.Annotations),
                        Parent = astType.Name,
                        Type = MapTypes(field.Types),
                        DescriptorType = DescriptorType.Field.ToString("g")
                    });
                }
            }
        }
Exemple #13
0
        public void Translate(IRInstruction instr, ILTranslator tr)
        {
            tr.PushOperand(instr.Operand1);
            tr.PushOperand(instr.Operand2);
            ASTType type = TypeInference.InferBinaryOp(instr.Operand1.Type, instr.Operand2.Type);

            switch (type)
            {
            case ASTType.I4:
                tr.Instructions.Add(new ILInstruction(ILOpCode.REM_DWORD));
                break;

            case ASTType.I8:
            case ASTType.Ptr:
                tr.Instructions.Add(new ILInstruction(ILOpCode.REM_QWORD));
                break;

            case ASTType.R4:
                tr.Instructions.Add(new ILInstruction(ILOpCode.REM_R32));
                break;

            case ASTType.R8:
                tr.Instructions.Add(new ILInstruction(ILOpCode.REM_R64));
                break;

            default:
                throw new NotSupportedException();
            }
            tr.PopOperand(instr.Operand1);
        }
 public static ILImmediate Create(object value, ASTType type)
 {
     return(new ILImmediate
     {
         Value = value,
         Type = type
     });
 }
        public override string VisitASTType(ASTType astType)
        {
            return(Intercept($@"
public class {astType.Name} {{
{string.Join(Environment.NewLine, astType.Fields.Select(Visit))}
}}
"));
        }
Exemple #16
0
 public ASTNode(Token op, ASTNode left, ASTNode right, ASTType type)
 {
     tokValue   = new Token();
     this.op    = op;
     this.left  = left;
     this.right = right;
     this.type  = type;
 }
Exemple #17
0
 public ASTNode(Token token, ASTOperand operand)
 {
     Token = token;
     Priority = 0;
     Operand = operand;
     Type = operand.Type;
     Operator = ASTOperator.None;
 }
Exemple #18
0
        public override string VisitASTType(ASTType astType)
        {
            var extensions     = astType.Extensions.Select(e => $"{astType.Name} --|> {e}");
            var fields         = astType.Fields.Select(f => $@"{f.Name}: {string.Join(" ", f.Types.Select(t => t.Value))}").ToList();
            var typeReferences = astType.Fields.Select(f =>
            {
                var _mod  = f.Types.First().Value;
                var _type = f.Types.Last().Value;
                if (_type != "String" &&
                    _type != "Number" &&
                    _type != "Decimal" &&
                    _type != "Boolean" &&
                    _type != "Date" &&
                    _type != "DateTime" &&
                    _type != "Time" &&
                    !_type.StartsWith("'", StringComparison.Ordinal))
                {
                    if (_mod == "List")
                    {
                        var min = f.Restrictions.FirstOrDefault(r => r.Key == "min")?.Value ?? "0";
                        var max = f.Restrictions.FirstOrDefault(r => r.Key == "max")?.Value ?? "*";

                        return($@"{astType.Name} --o ""{min}..{max}"" {_type}");
                    }
                    else
                    {
                        return($@"{astType.Name} --o {_type}");
                    }
                }
                else
                {
                    return("");
                }
            });

            if (astType.Fields.Any())
            {
                var template = $@"
class {astType.Name} {{
{string.Join(Environment.NewLine, fields)}
}}
{string.Join(Environment.NewLine, extensions)}
{string.Join(Environment.NewLine, typeReferences)}
";
                this.Parts.Add(template);
                return(template);
            }
            else
            {
                var template = $@"
class {astType.Name}
{string.Join(Environment.NewLine, extensions)}
";
                Parts.Add(template);
                return(template);
            }
        }
 public static ASTType InferShiftOp(ASTType a, ASTType b)
 {
     if ((b == ASTType.Ptr || b == ASTType.I4) &&
         (a == ASTType.I4 || b == ASTType.I4 || a == ASTType.Ptr))
     {
         return(a);
     }
     throw new ArgumentException("Invalid Shift Op Operand Types.");
 }
Exemple #20
0
 public ASTNode(ASTType _type, string _rule, string _term, int _start, int _end, Dictionary <string, ASTNode> _childs)
 {
     Type            = _type;
     RuleName        = _rule;
     RuleTerm        = _term;
     Text.IndexStart = _start;
     Text.IndexEnd   = _end;
     Childs          = _childs;
 }
Exemple #21
0
        public override IEnumerable <string> VisitASTType(ASTType astType)
        {
            yield return(astType.Name);

            foreach (var field in astType.Fields)
            {
                yield return(Visit(field).First());
            }
        }
Exemple #22
0
 public ASTNode(Token token, ASTType type, long value)
 {
     Token = token;
     Type = type;
     Operator = ASTOperator.None;
     Operand = null;
     IValue = value;
     Computed = true;
 }
Exemple #23
0
 public ASTNode(ASTType _type, string _rule, string _term, int _start, int _end, string _value)
 {
     Type            = _type;
     RuleName        = _rule;
     RuleTerm        = _term;
     Text.IndexStart = _start;
     Text.IndexEnd   = _end;
     Text.Value      = _value;
     Childs          = new Dictionary <string, ASTNode>();
 }
Exemple #24
0
 public ASTNode(ASTType _type, string _rule, string _term, int _start, int _end)
 {
     Parent          = null;
     Type            = _type;
     RuleName        = _rule;
     RuleTerm        = _term;
     Text.IndexStart = _start;
     Text.IndexEnd   = _end;
     Childs          = new  Dictionary <string, ASTNode>();
 }
Exemple #25
0
        public JSchema Create(ASTType astType, IEnumerable <IASTNode> nodes)
        {
            this.Nodes = nodes.ToList();
            var schema = MapAstNode(astType.Name);

            schema.SchemaVersion = new Uri("http://json-schema.org/draft-07/schema#");
            schema.Title         = astType.Name;
            schema.Description   = JsonMapper.Annotate(astType.Annotations);
            schema.ExtensionData.Add("references", References);
            return(schema);
        }
Exemple #26
0
        public void MultipleFieldsParserTest()
        {
            var code      = @"
type Person =
    @ The First Name of the Person
    @ A second Annotation is always cool to add
    FirstName: String;
    LastName: String;
    @ Age as a number is weird ofc!
    Age: Number;
";
            var tokens    = new Lexer().Lex(code);
            var parseTree = new Parser(tokens).Parse();

            Assert.NotNull(parseTree);

            List <IASTNode> list = parseTree.ToList();

            Assert.Single(list);

            ASTType t = list[0] as ASTType;

            Assert.Equal("Person", t.Name);
            Assert.Empty(t.Parameters);
            Assert.Equal(3, t.Fields.Count());


            List <ASTTypeField> fields = t.Fields.ToList();
            ASTTypeField        field  = fields.First();

            Assert.Equal(2, field.Annotations.Count());
            Assert.True(field.Annotations.First() is ASTAnnotation);
            Assert.Equal("The First Name of the Person", field.Annotations.First().Value);
            Assert.Equal("A second Annotation is always cool to add", field.Annotations.ToList()[1].Value);

            Assert.Equal("FirstName", field.Name);
            Assert.Equal("String", field.Type.First().Value);


            ASTTypeField lastNameField = fields[1];

            Assert.Equal("LastName", lastNameField.Name);
            Assert.Equal("String", lastNameField.Type.First().Value);
            Assert.Empty(lastNameField.Annotations);

            ASTTypeField ageField = fields[2];

            Assert.Equal("Age", ageField.Name);
            Assert.Equal(new List <ASTTypeDefinition>()
            {
                new ASTTypeDefinition("Number")
            }, ageField.Type);
            Assert.Single(ageField.Annotations);
        }
Exemple #27
0
		public static void EmitCompareEq(IRTranslator tr, ASTType type, IIROperand a, IIROperand b) {
			if (type == ASTType.O || type == ASTType.ByRef ||
			    type == ASTType.R4 || type == ASTType.R8) {
				tr.Instructions.Add(new IRInstruction(IROpCode.CMP, a, b));
			}
			else {
				// I4/I8/Ptr
				Debug.Assert(type == ASTType.I4 || type == ASTType.I8 || type == ASTType.Ptr);
				tr.Instructions.Add(new IRInstruction(IROpCode.CMP, a, b));
			}
		}
        public override string VisitASTType(ASTType astType)
        {
            if (!done.Contains(astType.Name))
            {
                return($@"
public interface {astType.Name} {{
{String.Join(Environment.NewLine, astType.Fields.Select(Visit).ToList())}
}}
");
            }
            return("");
        }
Exemple #29
0
        public IRVariable AllocateVRegister(ASTType type)
        {
            var vReg = new IRVariable {
                Id           = vRegs.Count,
                Name         = "vreg_" + vRegs.Count,
                Type         = type,
                VariableType = IRVariableType.VirtualRegister
            };

            vRegs.Add(vReg);
            return(vReg);
        }
        public static ILOpCode GetSIND(ASTType type, TypeSig rawType)
        {
            if (rawType != null)
            {
                switch (rawType.ElementType)
                {
                case ElementType.I1:
                case ElementType.U1:
                case ElementType.Boolean:
                    return(ILOpCode.SIND_BYTE);

                case ElementType.I2:
                case ElementType.U2:
                case ElementType.Char:
                    return(ILOpCode.SIND_WORD);

                case ElementType.I4:
                case ElementType.U4:
                case ElementType.R4:
                    return(ILOpCode.SIND_DWORD);

                case ElementType.I8:
                case ElementType.U8:
                case ElementType.R8:
                    return(ILOpCode.SIND_QWORD);

                case ElementType.Ptr:
                case ElementType.I:
                case ElementType.U:
                    return(ILOpCode.SIND_PTR);

                default:
                    return(ILOpCode.SIND_OBJECT);
                }
            }
            switch (type)
            {
            case ASTType.I4:
            case ASTType.R4:
                return(ILOpCode.SIND_DWORD);

            case ASTType.I8:
            case ASTType.R8:
                return(ILOpCode.SIND_QWORD);

            case ASTType.Ptr:
                return(ILOpCode.SIND_PTR);

            default:
                return(ILOpCode.SIND_OBJECT);
            }
        }
Exemple #31
0
        public IRVariable AllocateVRegister(ASTType type)
        {
            var vReg = new IRVariable
            {
                Id           = this.vRegs.Count,
                Name         = $"vreg_{this.vRegs.Count}",
                Type         = type,
                VariableType = IRVariableType.VirtualRegister
            };

            this.vRegs.Add(vReg);
            return(vReg);
        }
Exemple #32
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType    valueType = value.Type;
            IRVariable t         = tr.Context.AllocateVRegister(ASTType.I4);
            IRVariable retVar    = tr.Context.AllocateVRegister(ASTType.I4);

            t.RawType = tr.Context.Method.Module.CorLibTypes.Int16;

            int rangechk = tr.VM.Runtime.VMCall.RANGECHK;
            int ckovf    = tr.VM.Runtime.VMCall.CKOVERFLOW;

            switch (valueType)
            {
            case ASTType.I4:
            case ASTType.I8:
            case ASTType.Ptr:
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI8(ushort.MinValue)));
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI8(short.MaxValue)));
                tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(rangechk), value));
                tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ckovf)));

                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, t, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.SX, retVar, t));
                break;

            case ASTType.R4:
            case ASTType.R8:
                IRVariable tmpVar = tr.Context.AllocateVRegister(ASTType.I8);
                IRVariable fl     = tr.Context.AllocateVRegister(ASTType.I4);
                tr.Instructions.Add(new IRInstruction(IROpCode.__SETF)
                {
                    Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmpVar, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
                {
                    Operand1 = fl,
                    Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.OVERFLOW)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ckovf), fl));
                value = tmpVar;
                goto case ASTType.I8;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
Exemple #33
0
        public void ComputeSingle()
        {
            this.Type = this.Right.Type;
            if (!this.Right.Computed)
                return;
            switch (this.Operator)
            {
                case ASTOperator.Not:
                    // FIXME check Right is a boolean
                    this.BValue = !this.Right.BValue;
                    break;

                case ASTOperator.Neg:
                    return;

                default:
                    throw new Exception();
            }
            this.Computed = true;
        }
Exemple #34
0
 public ASTStatement PushInteger(Token token, ASTType type, long value)
 {
     ASTNode node = new ASTNode(token, type, value);
     addPostFixOperand(node);
     return this;
 }