├── Nova.Antlr ├── App.config ├── Program.cs ├── AntlrTool.cs ├── Properties │ └── AssemblyInfo.cs ├── Nova.Antlr.csproj └── bin │ └── Debug │ ├── NovaLexer.g4 │ └── NovaParser.g4 ├── Nova.Compiler ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── Program.cs └── Nova.Compiler.csproj ├── Nova.Bytecode ├── Enums │ ├── MethodType.cs │ ├── ModifiersEnum.cs │ ├── ContainerType.cs │ ├── OperatorsEnum.cs │ └── NativesEnum.cs ├── IO │ ├── IByteElement.cs │ ├── MainPointEntry.cs │ ├── ByteField.cs │ ├── Symbol.cs │ ├── ByteClass.cs │ ├── ByteMethod.cs │ └── NovFile.cs ├── Codes │ ├── ICode.cs │ ├── DuplicateCode.cs │ ├── AddCode.cs │ ├── DivCode.cs │ ├── MulCode.cs │ ├── SubCode.cs │ ├── ReturnCode.cs │ ├── VectCreateCode.cs │ ├── LoadClassCode.cs │ ├── PushNullCode.cs │ ├── StructPushCurrent.cs │ ├── PushIntCode.cs │ ├── LoadCode.cs │ ├── JumpCode.cs │ ├── StoreCode.cs │ ├── StructCreateCode.cs │ ├── JumpIfFalseCode.cs │ ├── PushConstCode.cs │ ├── NativeCallCode.cs │ ├── StructCallMethodCode.cs │ ├── ComparaisonCode.cs │ ├── StructLoadMemberCode.cs │ ├── StructStoreMemberCode.cs │ ├── CtorCallCode.cs │ ├── MethodCallCode.cs │ ├── StoreGlobalCode.cs │ └── LoadGlobalCode.cs ├── Symbols │ ├── SymbolType.cs │ ├── Symbol.cs │ └── SymbolTable.cs ├── Properties │ └── AssemblyInfo.cs ├── Generation │ └── ByteBlock.cs └── Nova.ByteCode.csproj ├── Nova ├── Expressions │ ├── Accessors │ │ ├── AccessorType.cs │ │ ├── IAccessorExpression.cs │ │ └── Accessor.cs │ ├── EmptyExpression.cs │ ├── ConstIntExpression.cs │ ├── ConstStringExpression.cs │ ├── ConstBoolExpression.cs │ ├── Expression.cs │ ├── VariableNameExpression.cs │ ├── NativeCallExpression.cs │ ├── MethodCallExpression.cs │ ├── ExpressionNode.cs │ ├── StructCallCtorStatement.cs │ └── OperatorExpression.cs ├── Members │ ├── Types.cs │ ├── IAccessible.cs │ ├── IChild.cs │ ├── ISemanticMember.cs │ ├── Interface.cs │ ├── Variable.cs │ ├── Field.cs │ ├── Class.cs │ └── Method.cs ├── IO │ ├── IByteData.cs │ ├── Using.cs │ ├── NvFile.cs │ ├── ClassesContainer.cs │ └── NovBuilder.cs ├── packages.config ├── CompilationState.cs ├── Parser │ ├── ParserUtils.cs │ ├── Errors │ │ └── NovaParsingErrorHandler.cs │ └── Listeners │ │ ├── ClassListener.cs │ │ ├── ClassMemberListener.cs │ │ ├── StatementListener.cs │ │ └── ExpressionListener.cs ├── Constants.cs ├── Types │ ├── TypeManager.cs │ └── NovaType.cs ├── Semantics │ ├── SemanticalError.cs │ └── SemanticsValidator.cs ├── Statements │ ├── EmptyStatement.cs │ ├── ReturnStatement.cs │ ├── Statement.cs │ ├── DeclarationStatement.cs │ ├── ExpressionStatement.cs │ ├── AssignationStatement.cs │ ├── VectorCreationStatement.cs │ ├── WhileStatement.cs │ ├── ForStatement.cs │ └── IfStatement.cs ├── Antlr │ ├── NovaLexer.tokens │ └── NovaParser.tokens ├── Properties │ └── AssemblyInfo.cs └── Nova.csproj ├── Standard Library ├── nova.nv └── nova2.nv ├── Nova.Utils ├── Constants.cs ├── IO │ ├── CppBinaryWriter.cs │ └── CppBinaryReader.cs ├── Properties │ └── AssemblyInfo.cs ├── Logger.cs └── Nova.Utils.csproj ├── Readme.md └── Nova.sln /Nova.Antlr/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Nova.Compiler/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Nova.Bytecode/Enums/MethodType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Bytecode.Enums 8 | { 9 | public enum MethodType 10 | { 11 | Method, 12 | Ctor, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Nova/Expressions/Accessors/AccessorType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Expressions.Accessors 8 | { 9 | public enum AccessorType 10 | { 11 | Field, 12 | Method, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Nova.Bytecode/Enums/ModifiersEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.ByteCode.Enums 8 | { 9 | public enum ModifiersEnum 10 | { 11 | @public = 0x1, 12 | @private = 0x2, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Nova/Members/Types.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Members 8 | { 9 | public enum Types 10 | { 11 | Unit, 12 | String, 13 | Int, 14 | Bool, 15 | Struct, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Nova.Bytecode/Enums/ContainerType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Bytecode.Enums 8 | { 9 | public enum ContainerType 10 | { 11 | @class = 0, 12 | @struct, 13 | primitive, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Nova/IO/IByteData.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.IO 9 | { 10 | public interface IByteData 11 | { 12 | IByteElement GetByteElement(ClassesContainer container, IByteElement parent); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Nova/Members/IAccessible.cs: -------------------------------------------------------------------------------- 1 | using Nova.Semantics; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.Members 9 | { 10 | public interface IAccessible 11 | { 12 | public Class GetContextualClass(SemanticsValidator validator); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Nova/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Nova.Bytecode/IO/IByteElement.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.ByteCode.IO 10 | { 11 | public interface IByteElement 12 | { 13 | void Serialize(CppBinaryWriter writer); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Nova/CompilationState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova 8 | { 9 | public enum CompilationState 10 | { 11 | Parsing, 12 | TypeLink, 13 | SemanticalValidation, 14 | BytecodeGeneration, 15 | End, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Nova/Members/IChild.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Members 8 | { 9 | public interface IChild 10 | { 11 | Class ParentClass 12 | { 13 | get; 14 | } 15 | IChild Parent 16 | { 17 | get; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Nova.Bytecode/Enums/OperatorsEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.ByteCode.Enums 8 | { 9 | public enum OperatorsEnum 10 | { 11 | Plus, 12 | Minus, 13 | Multiply, 14 | Divide, 15 | Equals, 16 | Different, 17 | Inferior, 18 | Superior, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Nova/Parser/ParserUtils.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Enums; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.Parser 9 | { 10 | class ParserUtils 11 | { 12 | public static ModifiersEnum ParseModifier(string modifier) 13 | { 14 | return (ModifiersEnum)Enum.Parse(typeof(ModifiersEnum), modifier); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/ICode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.ByteCode.Codes 10 | { 11 | public interface ICode 12 | { 13 | int OpId 14 | { 15 | get; 16 | } 17 | 18 | void Serialize(CppBinaryWriter writer); 19 | 20 | int GetSize(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Nova.Bytecode/Enums/NativesEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Bytecode.Enums 8 | { 9 | public enum NativesEnum 10 | { 11 | Unknown = 0, 12 | Print = 1, 13 | Readl = 2, 14 | GetVectSize = 3, 15 | AddVect = 4, 16 | AtVect = 5, 17 | SetVect = 6, 18 | StrGet = 7, 19 | NewLine = 8, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Nova/Members/ISemanticMember.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Generation; 2 | using Nova.IO; 3 | using Nova.Semantics; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Nova.Members 11 | { 12 | public interface ISemanticMember 13 | { 14 | void GenerateBytecode(ClassesContainer container, ByteBlock context); 15 | 16 | void ValidateSemantics(SemanticsValidator validator); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Nova.Bytecode/Symbols/SymbolType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Bytecode.Symbols 8 | { 9 | public enum SymbolType 10 | { 11 | Unknown = 0, 12 | Local, // human (where human is a local variable) 13 | ClassMember, // human where human is a class field. 14 | StructMember, // human where human is a struct field 15 | ExternalMember, // Class.Field (public static) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/DuplicateCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class DuplicateCode : ICode 12 | { 13 | public int OpId => 29; 14 | 15 | public int GetSize() 16 | { 17 | return 0; 18 | } 19 | 20 | public void Serialize(CppBinaryWriter writer) 21 | { 22 | 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Standard Library/nova.nv: -------------------------------------------------------------------------------- 1 | 2 | primitive unit 3 | { 4 | 5 | } 6 | 7 | primitive char 8 | { 9 | 10 | } 11 | primitive string 12 | { 13 | public char get(string self,int index) 14 | { 15 | return ~StrGet(self,index) 16 | } 17 | } 18 | primitive int 19 | { 20 | public int MaxValue = 2147483647 21 | public int MinValue = -2147483647 22 | 23 | public int pow2(int self) 24 | { 25 | return self * self 26 | } 27 | } 28 | 29 | class Nova 30 | { 31 | public unit Print(string value) 32 | { 33 | ~Print(value) 34 | } 35 | public unit PrintLine(string value) 36 | { 37 | ~Print(value) 38 | ~NewLine() 39 | } 40 | 41 | } 42 | 43 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/AddCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class AddCode : ICode 12 | { 13 | public int OpId => 1; 14 | 15 | public int GetSize() 16 | { 17 | return 0; 18 | } 19 | 20 | public void Serialize(CppBinaryWriter writer) 21 | { 22 | 23 | } 24 | public override string ToString() 25 | { 26 | return "(" + OpId + ") " + "Add"; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/DivCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class DivCode : ICode 12 | { 13 | public int OpId => 4; 14 | 15 | public int GetSize() 16 | { 17 | return 0; 18 | } 19 | 20 | public void Serialize(CppBinaryWriter writer) 21 | { 22 | 23 | } 24 | public override string ToString() 25 | { 26 | return "(" + OpId + ") " + "Div"; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/MulCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class MulCode : ICode 12 | { 13 | public int OpId => 12; 14 | 15 | public int GetSize() 16 | { 17 | return 0; 18 | } 19 | 20 | public void Serialize(CppBinaryWriter writer) 21 | { 22 | 23 | } 24 | public override string ToString() 25 | { 26 | return "(" + OpId + ") " + "Mul"; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/SubCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class SubCode : ICode 12 | { 13 | public int OpId => 27; 14 | 15 | public int GetSize() 16 | { 17 | return 0; 18 | } 19 | 20 | public void Serialize(CppBinaryWriter writer) 21 | { 22 | 23 | } 24 | public override string ToString() 25 | { 26 | return "(" + OpId + ") " + "Sub"; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Nova/IO/Using.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.IO 8 | { 9 | public enum UsingType 10 | { 11 | Ref, 12 | Std, 13 | } 14 | public class Using 15 | { 16 | public UsingType Type 17 | { 18 | get; 19 | set; 20 | } 21 | public string Value 22 | { 23 | get; 24 | set; 25 | } 26 | public Using(UsingType type,string value) 27 | { 28 | this.Type = type; 29 | this.Value = value; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Nova/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova 9 | { 10 | public class Constants 11 | { 12 | public const string BytecodeFileExtension = ".nov"; 13 | 14 | public const string NovaSourceFileExtension = ".nv"; 15 | 16 | public const string DefaultOuputPath = "output.nov"; 17 | 18 | public const string NovFileHeader = "NEXEC"; 19 | 20 | public const string MainPointEntryMethodName = "main"; 21 | 22 | public const string STDVectorClassName = "Vector"; // weird stuff here 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/ReturnCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.ByteCode.Codes 10 | { 11 | public class ReturnCode : ICode 12 | { 13 | public int OpId => 18; 14 | 15 | public ReturnCode() 16 | { 17 | 18 | } 19 | public void Serialize(CppBinaryWriter writer) 20 | { 21 | 22 | } 23 | public int GetSize() 24 | { 25 | return 0; 26 | } 27 | public override string ToString() 28 | { 29 | return "(" + OpId + ") " + "Return"; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/VectCreateCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class VectCreateCode : ICode 12 | { 13 | public int OpId => 28; 14 | 15 | private int size; 16 | 17 | public VectCreateCode(int size) 18 | { 19 | this.size = size; 20 | } 21 | 22 | public int GetSize() 23 | { 24 | return 1; 25 | } 26 | 27 | public void Serialize(CppBinaryWriter writer) 28 | { 29 | writer.Write(size); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/LoadClassCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class LoadClassCode : ICode 12 | { 13 | public int OpId => 29; 14 | 15 | private int classId; 16 | 17 | public LoadClassCode(int classId) 18 | { 19 | this.classId = classId; 20 | } 21 | 22 | public int GetSize() 23 | { 24 | return 1; 25 | } 26 | 27 | public void Serialize(CppBinaryWriter writer) 28 | { 29 | writer.Write(classId); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/PushNullCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class PushNullCode : ICode 12 | { 13 | public int OpId => 16; 14 | 15 | public PushNullCode() 16 | { 17 | 18 | } 19 | 20 | public override string ToString() 21 | { 22 | return "(" + OpId + ") " + "PushNull"; 23 | } 24 | 25 | public void Serialize(CppBinaryWriter writer) 26 | { 27 | 28 | } 29 | public int GetSize() 30 | { 31 | return 0; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Nova/Members/Interface.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Enums; 2 | using Nova.IO; 3 | using Nova.Semantics; 4 | using Nova.Statements; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace Nova.Members 13 | { 14 | public class Interface 15 | { 16 | public const string INTERFACE_PATTERN = @"^\s*interface\s+([a-zA-Z_$][a-zA-Z_$0-9]*)$"; 17 | 18 | public Class ParentClass => throw new NotImplementedException(); 19 | 20 | public string Name => throw new NotImplementedException(); 21 | 22 | public ModifiersEnum Modifiers => throw new NotImplementedException(); 23 | 24 | public IChild Parent => throw new NotImplementedException(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Nova/Expressions/EmptyExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.ByteCode.Generation; 3 | using Nova.IO; 4 | using Nova.Members; 5 | using Nova.Semantics; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace Nova.Expressions 13 | { 14 | public class EmptyExpression : Expression 15 | { 16 | public EmptyExpression(IChild parent, ParserRuleContext context) : base(parent, context) 17 | { 18 | 19 | } 20 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 21 | { 22 | 23 | } 24 | 25 | public override void ValidateSemantics(SemanticsValidator validator) 26 | { 27 | 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/StructPushCurrent.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | /* 12 | * human.Name = "value" 13 | */ 14 | public class StructPushCurrent : ICode 15 | { 16 | public int OpId => 25; 17 | 18 | public StructPushCurrent() 19 | { 20 | 21 | } 22 | 23 | public void Serialize(CppBinaryWriter writer) 24 | { 25 | } 26 | public override string ToString() 27 | { 28 | return "(" + OpId + ") " + "StructPushCurrent"; 29 | } 30 | public int GetSize() 31 | { 32 | return 0; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Nova.Utils/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.Utils 9 | { 10 | public class Constants 11 | { 12 | public const string INTERMEDIATE_LANGUAGE_FILE_EXTENSION = ".nov"; 13 | 14 | public const string SOURCE_CODE_FILE_EXTENSION = ".nv"; 15 | 16 | public const string DEFAULT_OUTPUT_PATH = "output.nov"; 17 | 18 | public const string NOV_FILE_HEADER = "NEXEC"; 19 | 20 | public const char BRACKET_START_DELIMITER = '{'; 21 | 22 | public const char BRACKET_END_DELIMITER = '}'; 23 | 24 | public const string MAIN_METHOD_NAME = "Main"; 25 | 26 | public static Assembly ASSEMBLY = Assembly.GetExecutingAssembly(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Nova/Parser/Errors/NovaParsingErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Misc; 3 | using Nova.Utils; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Nova.Parser.Errors 11 | { 12 | public class NovaParsingErrorHandler : IAntlrErrorListener 13 | { 14 | public int ErrorsCount 15 | { 16 | get; 17 | set; 18 | } 19 | public void SyntaxError([NotNull] IRecognizer recognizer, [Nullable] IToken offendingSymbol, int line, int charPositionInLine, [NotNull] string msg, [Nullable] RecognitionException e) 20 | { 21 | Logger.Write(line + ":" + charPositionInLine + " " + msg, LogType.SyntaxicError); 22 | ErrorsCount++ ; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/PushIntCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.ByteCode.Codes 10 | { 11 | public class PushIntCode : ICode 12 | { 13 | public int OpId => 15; 14 | 15 | private int value; 16 | 17 | public PushIntCode(int value) 18 | { 19 | this.value = value; 20 | } 21 | public override string ToString() 22 | { 23 | return "(" + OpId + ") " + "PushInt " + value; 24 | } 25 | 26 | public void Serialize(CppBinaryWriter writer) 27 | { 28 | writer.Write(value); 29 | } 30 | public int GetSize() 31 | { 32 | return 1; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Nova/Expressions/Accessors/IAccessorExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.Members; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Expressions.Accessors 10 | { 11 | public abstract class AccessorExpression : Expression 12 | { 13 | public AccessorExpression ParentAccessor 14 | { 15 | get; 16 | set; 17 | } 18 | public string Name 19 | { 20 | get; 21 | set; 22 | } 23 | public abstract AccessorType AccessorType 24 | { 25 | get; 26 | } 27 | public AccessorExpression(IChild parent, ParserRuleContext context) : base(parent, context) 28 | { 29 | 30 | } 31 | 32 | 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Nova.Bytecode/Symbols/Symbol.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.IO; 2 | using Nova.Utils; 3 | using Nova.Utils.IO; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Nova.Bytecode.Symbols 11 | { 12 | public class Symbol : IByteElement 13 | { 14 | public int Id; 15 | public string Type; // useless ? 16 | 17 | public Symbol(int id,string type) 18 | { 19 | this.Id = id; 20 | this.Type = type; 21 | } 22 | 23 | 24 | public void Serialize(CppBinaryWriter writer) 25 | { 26 | writer.Write(Id); 27 | writer.Write(Type); 28 | } 29 | public override string ToString() 30 | { 31 | return "{" + Id + ": " + Type + "}"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Standard Library/nova2.nv: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | struct ListElement 5 | { 6 | public ListElement Next 7 | public string Value 8 | 9 | } 10 | struct List 11 | { 12 | public ListElement Head 13 | public int Size 14 | 15 | public ListElement Current 16 | 17 | -> List() 18 | { 19 | Head = -> ListElement() 20 | Current = Head 21 | Size = 0 22 | } 23 | public void Add(string element) 24 | { 25 | if (Size == 0) 26 | { 27 | Current.Value = element 28 | } 29 | else 30 | { 31 | Current.Next = -> ListElement() 32 | Current.Next.Value = element 33 | Current = Current.Next 34 | } 35 | 36 | Size = Size + 1 37 | } 38 | public void Print() 39 | { 40 | ListElement current = Head 41 | 42 | int i = 0 43 | 44 | while (i < Size) 45 | { 46 | Nova.Print(current.Value) 47 | current = current.Next 48 | i = i + 1 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Nova/Types/TypeManager.cs: -------------------------------------------------------------------------------- 1 | using Nova.IO; 2 | using Nova.Members; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Types 10 | { 11 | public class TypeManager 12 | { 13 | private Dictionary Types = new Dictionary(); 14 | 15 | public TypeManager() 16 | { 17 | } 18 | 19 | 20 | public NovaType GetTypeInstance(string type) 21 | { 22 | NovaType result = null; 23 | Types.TryGetValue(type, out result); 24 | return result; 25 | } 26 | 27 | public void Register(Class @class, bool primitive) 28 | { 29 | NovaType type = new NovaType(@class, primitive); 30 | Types.Add(type.Name, type); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/LoadCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.ByteCode.Codes 10 | { 11 | public class LoadCode : ICode 12 | { 13 | public int OpId => 7; 14 | 15 | private int variableId; 16 | 17 | public LoadCode(int variableId) 18 | { 19 | this.variableId = variableId; 20 | } 21 | 22 | public override string ToString() 23 | { 24 | return "(" + OpId + ") " + "Load " + variableId; 25 | } 26 | 27 | public void Serialize(CppBinaryWriter writer) 28 | { 29 | writer.Write(variableId); 30 | } 31 | public int GetSize() 32 | { 33 | return 1; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/JumpCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.ByteCode.Codes 10 | { 11 | public class JumpCode : ICode 12 | { 13 | public int OpId => 5; 14 | 15 | public int targetIndex; 16 | 17 | public JumpCode(int targetIndex) 18 | { 19 | this.targetIndex = targetIndex; 20 | } 21 | 22 | public void Serialize(CppBinaryWriter writer) 23 | { 24 | writer.Write(targetIndex); 25 | } 26 | 27 | public override string ToString() 28 | { 29 | return "(" + OpId + ") " + "Jump " + targetIndex; 30 | } 31 | public int GetSize() 32 | { 33 | return 1; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/StoreCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.ByteCode.Codes 10 | { 11 | public class StoreCode : ICode 12 | { 13 | public int OpId => 19; 14 | 15 | private int variableId; 16 | 17 | public StoreCode(int variableId) 18 | { 19 | this.variableId = variableId; 20 | } 21 | 22 | public void Serialize(CppBinaryWriter writer) 23 | { 24 | writer.Write(variableId); 25 | } 26 | 27 | public override string ToString() 28 | { 29 | return "(" + OpId + ") " + "Store " + variableId; 30 | } 31 | public int GetSize() 32 | { 33 | return 1; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/StructCreateCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class StructCreateCode : ICode 12 | { 13 | public int OpId => 23; 14 | 15 | private int classId; 16 | 17 | public StructCreateCode(int classId) 18 | { 19 | this.classId = classId; 20 | } 21 | public override string ToString() 22 | { 23 | return "(" + OpId + ") " + "StructCreate " + classId; 24 | } 25 | public void Serialize(CppBinaryWriter writer) 26 | { 27 | writer.Write(classId); 28 | } 29 | public int GetSize() 30 | { 31 | return 1; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/JumpIfFalseCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.ByteCode.Codes 10 | { 11 | public class JumpIfFalseCode : ICode 12 | { 13 | public int OpId => 6; 14 | 15 | public int targetIndex; 16 | 17 | public JumpIfFalseCode(int index) 18 | { 19 | this.targetIndex = index; 20 | } 21 | 22 | public override string ToString() 23 | { 24 | return "(" + OpId + ") " + "JumpIfFalse " + targetIndex; 25 | } 26 | 27 | public void Serialize(CppBinaryWriter writer) 28 | { 29 | writer.Write(targetIndex); 30 | } 31 | public int GetSize() 32 | { 33 | return 1; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Nova.Bytecode/IO/MainPointEntry.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.IO; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.IO 10 | { 11 | public class MainPointEntry : IByteElement 12 | { 13 | public int ClassIndex 14 | { 15 | get; 16 | set; 17 | } 18 | public int MethodIndex 19 | { 20 | get; 21 | set; 22 | } 23 | public MainPointEntry(int classIndex,int methodIndex) 24 | { 25 | this.ClassIndex = classIndex; 26 | this.MethodIndex = methodIndex; 27 | } 28 | public void Serialize(CppBinaryWriter writer) 29 | { 30 | writer.Write(ClassIndex); 31 | writer.Write(MethodIndex); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/PushConstCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class PushConstCode : ICode 12 | { 13 | public int OpId => 14; 14 | 15 | private int constantId; 16 | 17 | public PushConstCode(int constantId) 18 | { 19 | this.constantId = constantId; 20 | } 21 | 22 | public override string ToString() 23 | { 24 | return "(" + OpId + ") " + "PushConst " + constantId; 25 | } 26 | 27 | public void Serialize(CppBinaryWriter writer) 28 | { 29 | writer.Write(constantId); 30 | } 31 | public int GetSize() 32 | { 33 | return 1; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/NativeCallCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Nova.ByteCode.Codes 11 | { 12 | public class NativeCallCode : ICode 13 | { 14 | public int OpId => 13; 15 | 16 | private int nativeId; 17 | 18 | public NativeCallCode(int nativeId) 19 | { 20 | this.nativeId = nativeId; 21 | } 22 | public override string ToString() 23 | { 24 | return "(" + OpId + ") " + "NativeId " + nativeId; 25 | } 26 | 27 | public void Serialize(CppBinaryWriter writer) 28 | { 29 | writer.Write(nativeId); 30 | } 31 | 32 | public int GetSize() 33 | { 34 | return 1; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/StructCallMethodCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class StructCallMethodCode : ICode 12 | { 13 | public int OpId => 22; 14 | 15 | private int methodId; 16 | 17 | public StructCallMethodCode(int methodId) 18 | { 19 | this.methodId = methodId; 20 | } 21 | public override string ToString() 22 | { 23 | return "(" + OpId + ") " + "StructCallMethod " + methodId; 24 | } 25 | public void Serialize(CppBinaryWriter writer) 26 | { 27 | writer.Write(methodId); 28 | } 29 | public int GetSize() 30 | { 31 | return 1; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/ComparaisonCode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Nova.ByteCode.Enums; 8 | using Nova.Utils.IO; 9 | 10 | namespace Nova.ByteCode.Codes 11 | { 12 | public class ComparaisonCode : ICode 13 | { 14 | private OperatorsEnum type; 15 | 16 | public int OpId => 2; 17 | 18 | public ComparaisonCode(OperatorsEnum type) 19 | { 20 | this.type = type; 21 | } 22 | 23 | public void Serialize(CppBinaryWriter writer) 24 | { 25 | writer.Write((int)type); 26 | } 27 | 28 | public override string ToString() 29 | { 30 | return "(" + OpId + ") " + "Comparaison" + type; 31 | } 32 | 33 | public int GetSize() 34 | { 35 | return 1; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Nova/Types/NovaType.cs: -------------------------------------------------------------------------------- 1 | using Nova.Members; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.Types 9 | { 10 | public class NovaType 11 | { 12 | public bool IsPrimitive 13 | { 14 | get; 15 | set; 16 | } 17 | 18 | public string Name 19 | { 20 | get 21 | { 22 | return Class.ClassName; 23 | } 24 | } 25 | 26 | public Class Class 27 | { 28 | get; 29 | set; 30 | } 31 | 32 | public NovaType(Class @class, bool isPrimitive) 33 | { 34 | this.Class = @class; 35 | this.IsPrimitive = isPrimitive; 36 | } 37 | 38 | public override string ToString() 39 | { 40 | return "NovaType {" + Name + "}"; 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/StructLoadMemberCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class StructLoadMemberCode : ICode 12 | { 13 | public int OpId => 24; 14 | 15 | private int propertyId; // propertyId (symbolTable) 16 | 17 | public StructLoadMemberCode(int propertyId) 18 | { 19 | this.propertyId = propertyId; 20 | } 21 | 22 | public void Serialize(CppBinaryWriter writer) 23 | { 24 | writer.Write(propertyId); 25 | } 26 | 27 | public override string ToString() 28 | { 29 | return "(" + OpId + ") " + "StructLoadMemberCode " + propertyId; 30 | } 31 | public int GetSize() 32 | { 33 | return 1; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/StructStoreMemberCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | /* 12 | * this.Age = value 13 | */ 14 | public class StructStoreMemberCode : ICode 15 | { 16 | public int OpId => 26; 17 | 18 | private int propertyId; 19 | 20 | public StructStoreMemberCode(int propertyId) 21 | { 22 | this.propertyId = propertyId; 23 | } 24 | 25 | public void Serialize(CppBinaryWriter writer) 26 | { 27 | writer.Write(propertyId); 28 | } 29 | 30 | public override string ToString() 31 | { 32 | return "(" + OpId + ") " + "StructStoreMember " + propertyId; 33 | } 34 | public int GetSize() 35 | { 36 | return 1; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Nova.Utils/IO/CppBinaryWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.Utils.IO 9 | { 10 | public class CppBinaryWriter : BinaryWriter 11 | { 12 | public CppBinaryWriter(Stream output) : base(output) 13 | { 14 | } 15 | 16 | public CppBinaryWriter(Stream output, Encoding encoding) : base(output, encoding) 17 | { 18 | } 19 | 20 | public CppBinaryWriter(Stream output, Encoding encoding, bool leaveOpen) : base(output, encoding, leaveOpen) 21 | { 22 | } 23 | 24 | protected CppBinaryWriter() 25 | { 26 | } 27 | 28 | public override void Write(string value) 29 | { 30 | for (int i = 0; i < value.Length; i++) 31 | { 32 | this.Write(value[i]); 33 | } 34 | this.Write('\0'); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Nova.Utils/IO/CppBinaryReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.Utils.IO 9 | { 10 | public class CppBinaryReader : BinaryReader 11 | { 12 | public CppBinaryReader(Stream input) : base(input) 13 | { 14 | } 15 | 16 | public CppBinaryReader(Stream input, Encoding encoding) : base(input, encoding) 17 | { 18 | } 19 | 20 | public CppBinaryReader(Stream input, Encoding encoding, bool leaveOpen) : base(input, encoding, leaveOpen) 21 | { 22 | } 23 | 24 | public override string ReadString() 25 | { 26 | string result = string.Empty; 27 | 28 | char read = this.ReadChar(); 29 | 30 | while (read != '\0') 31 | { 32 | result += read; 33 | read = this.ReadChar(); 34 | } 35 | return result; 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/CtorCallCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Codes 10 | { 11 | public class CtorCallCode : ICode 12 | { 13 | public int OpId => 3; 14 | 15 | private int parametersCount; 16 | 17 | private int methodId; 18 | 19 | public CtorCallCode(int methodId, int parametersCount) 20 | { 21 | this.methodId = methodId; 22 | this.parametersCount = parametersCount; 23 | } 24 | public override string ToString() 25 | { 26 | return "(" + OpId + ") " + "CtorCall " + parametersCount; 27 | } 28 | public void Serialize(CppBinaryWriter writer) 29 | { 30 | writer.Write(parametersCount); 31 | writer.Write(methodId); 32 | } 33 | public int GetSize() 34 | { 35 | return 2; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/MethodCallCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Nova.Bytecode.Codes 11 | { 12 | public class MethodCallCode : ICode 13 | { 14 | public int OpId => 11; 15 | 16 | private int classId; 17 | private int methodId; 18 | 19 | public MethodCallCode(int classId, int methodId) 20 | { 21 | this.classId = classId; 22 | this.methodId = methodId; 23 | } 24 | 25 | public override string ToString() 26 | { 27 | return "(" + OpId + ") " + "MethodCall " + classId + " " + methodId; 28 | } 29 | public void Serialize(CppBinaryWriter writer) 30 | { 31 | writer.Write(classId); 32 | writer.Write(methodId); 33 | } 34 | public int GetSize() 35 | { 36 | return 2; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/StoreGlobalCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Nova.Bytecode.Codes 11 | { 12 | public class StoreGlobalCode : ICode 13 | { 14 | public int OpId => 21; 15 | 16 | private int classId; 17 | 18 | private int fieldId; 19 | 20 | public StoreGlobalCode(int classId,int fieldId) 21 | { 22 | this.classId = classId; 23 | this.fieldId = fieldId; 24 | } 25 | 26 | public override string ToString() 27 | { 28 | return "(" + OpId + ") " + "StoreGlobal " + classId + " " + fieldId; 29 | } 30 | public void Serialize(CppBinaryWriter writer) 31 | { 32 | writer.Write(classId); 33 | writer.Write(fieldId); 34 | } 35 | public int GetSize() 36 | { 37 | return 2; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Nova.Antlr/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Antlr 8 | { 9 | class Program 10 | { 11 | private const string LexerPath = "NovaLexer.g4"; 12 | private const string ParserPath = "NovaParser.g4"; 13 | 14 | private const string OutputPath = @"C:\Users\Skinz\Desktop\Nova\Compiler\Nova\Antlr"; 15 | 16 | static void Main(string[] args) 17 | { 18 | AntlrTool tool = new AntlrTool("antlr4-csharp-4.6.6-complete.jar"); 19 | 20 | bool lexer = tool.Generate(LexerPath, OutputPath); 21 | bool parser = tool.Generate(ParserPath, OutputPath); 22 | 23 | if (lexer && parser) 24 | { 25 | Console.WriteLine("Antlr files generated."); 26 | } 27 | else 28 | { 29 | Console.WriteLine("Antlr generation ended with errors..."); 30 | } 31 | Console.Read(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Nova/Expressions/ConstIntExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.Bytecode.Codes; 3 | using Nova.ByteCode.Codes; 4 | using Nova.ByteCode.Generation; 5 | using Nova.IO; 6 | using Nova.Members; 7 | using Nova.Semantics; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace Nova.Expressions 15 | { 16 | public class ConstIntExpression : Expression 17 | { 18 | private int Value 19 | { 20 | get; 21 | set; 22 | } 23 | public ConstIntExpression(IChild parent, ParserRuleContext context, int value) : base(parent, context) 24 | { 25 | this.Value = value; 26 | } 27 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 28 | { 29 | context.Instructions.Add(new PushIntCode(Value)); 30 | } 31 | 32 | public override void ValidateSemantics(SemanticsValidator validator) 33 | { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Nova.Bytecode/Codes/LoadGlobalCode.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode; 2 | using Nova.ByteCode.Codes; 3 | using Nova.Utils.IO; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace Nova.Bytecode.Codes 12 | { 13 | public class LoadGlobalCode : ICode 14 | { 15 | public int OpId => 8; 16 | 17 | private int classId; 18 | 19 | private int fieldId; 20 | 21 | public LoadGlobalCode(int classId, int fieldId) 22 | { 23 | this.classId = classId; 24 | this.fieldId = fieldId; 25 | } 26 | 27 | public override string ToString() 28 | { 29 | return "(" + OpId + ") " + "LoadGlobal " + classId + " " + fieldId; 30 | } 31 | public void Serialize(CppBinaryWriter writer) 32 | { 33 | writer.Write(classId); 34 | writer.Write(fieldId); 35 | } 36 | public int GetSize() 37 | { 38 | return 2; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Nova/Semantics/SemanticalError.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Semantics 10 | { 11 | public class SemanticalError 12 | { 13 | private string Filepath 14 | { 15 | get; 16 | set; 17 | } 18 | private string Message 19 | { 20 | get; 21 | set; 22 | } 23 | private ParserRuleContext Context 24 | { 25 | get; 26 | set; 27 | } 28 | public SemanticalError(string filepath, string message, ParserRuleContext context) 29 | { 30 | this.Filepath = filepath; 31 | this.Message = message; 32 | this.Context = context; // starting from 1 33 | } 34 | public override string ToString() 35 | { 36 | return "File: " + Path.GetFileName(Filepath) + " " + Message + " at line " + Context.start.Line; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Nova/Statements/EmptyStatement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Nova.ByteCode.Codes; 8 | using Nova.ByteCode.Generation; 9 | using Nova.Lexer; 10 | using Nova.IO; 11 | using Nova.Members; 12 | using Nova.Semantics; 13 | using Antlr4.Runtime; 14 | 15 | namespace Nova.Statements 16 | { 17 | public class EmptyStatement : Statement 18 | { 19 | public EmptyStatement(IChild member, ParserRuleContext context) : base(member, context) 20 | { 21 | 22 | } 23 | 24 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | 29 | public override void ValidateSemantics(SemanticsValidator validator) 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | 34 | public override void ValidateTypes(SemanticsValidator validator) 35 | { 36 | throw new NotImplementedException(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Nova/Expressions/ConstStringExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.Bytecode.Codes; 3 | using Nova.ByteCode.Generation; 4 | using Nova.IO; 5 | using Nova.Members; 6 | using Nova.Semantics; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace Nova.Expressions 14 | { 15 | public class ConstStringExpression : Expression 16 | { 17 | private string Value 18 | { 19 | get; 20 | set; 21 | } 22 | public ConstStringExpression(IChild parent, ParserRuleContext context, string value) : base(parent, context) 23 | { 24 | this.Value = value; 25 | } 26 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 27 | { 28 | int constantId = context.BindConstant(Value); 29 | context.Instructions.Add(new PushConstCode(constantId)); 30 | } 31 | 32 | public override void ValidateSemantics(SemanticsValidator validator) 33 | { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Nova/Expressions/ConstBoolExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.Bytecode.Codes; 3 | using Nova.ByteCode.Codes; 4 | using Nova.ByteCode.Generation; 5 | using Nova.IO; 6 | using Nova.Members; 7 | using Nova.Semantics; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace Nova.Expressions 15 | { 16 | public class ConstBoolExpression : Expression 17 | { 18 | private bool Value 19 | { 20 | get; 21 | set; 22 | } 23 | public ConstBoolExpression(IChild parent, ParserRuleContext context, bool value) : base(parent, context) 24 | { 25 | this.Value = value; 26 | } 27 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 28 | { 29 | int value = Value == true ? 1 : 0; 30 | context.Instructions.Add(new PushIntCode(value)); // rather push byte ! 31 | } 32 | 33 | public override void ValidateSemantics(SemanticsValidator validator) 34 | { 35 | 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Nova/Expressions/Expression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.ByteCode.Generation; 3 | using Nova.IO; 4 | using Nova.Members; 5 | using Nova.Semantics; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace Nova.Expressions 13 | { 14 | public abstract class Expression : ISemanticMember, IChild 15 | { 16 | public Class ParentClass => Parent.ParentClass; 17 | 18 | public IChild Parent 19 | { 20 | get; 21 | private set; 22 | } 23 | public ParserRuleContext ParsingContext 24 | { 25 | get; 26 | private set; 27 | } 28 | public Expression(IChild parent,ParserRuleContext context) 29 | { 30 | this.Parent = parent; 31 | this.ParsingContext = context; 32 | } 33 | public abstract void GenerateBytecode(ClassesContainer container, ByteBlock context); 34 | 35 | public abstract void ValidateSemantics(SemanticsValidator validator); 36 | 37 | public override string ToString() 38 | { 39 | return this.GetType().Name; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Nova/Statements/ReturnStatement.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.ByteCode.Generation; 3 | using Nova.Lexer; 4 | using Nova.IO; 5 | using Nova.Members; 6 | using Nova.Semantics; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Text.RegularExpressions; 13 | using System.Threading.Tasks; 14 | using Antlr4.Runtime; 15 | 16 | namespace Nova.Statements 17 | { 18 | public class ReturnStatement : Statement 19 | { 20 | public ExpressionNode Value 21 | { 22 | get; 23 | set; 24 | } 25 | public ReturnStatement(IChild parent, ParserRuleContext context) : base(parent, context) 26 | { 27 | 28 | } 29 | 30 | 31 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 32 | { 33 | if (!Value.Empty) 34 | { 35 | Value.GenerateBytecode(container, context); 36 | } 37 | context.Instructions.Add(new ReturnCode()); 38 | } 39 | 40 | public override void ValidateSemantics(SemanticsValidator validator) 41 | { 42 | Value.ValidateSemantics(validator); 43 | } 44 | 45 | public override void ValidateTypes(SemanticsValidator validator) 46 | { 47 | 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Nova/Statements/Statement.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.ByteCode.Generation; 3 | using Nova.ByteCode.IO; 4 | using Nova.Lexer; 5 | using Nova.IO; 6 | using Nova.Members; 7 | using Nova.Semantics; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.IO; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using Nova.Bytecode.Symbols; 15 | using Nova.Bytecode.Enums; 16 | using Antlr4.Runtime; 17 | 18 | namespace Nova.Statements 19 | { 20 | public abstract class Statement : ISemanticMember , IChild 21 | { 22 | public IChild Parent 23 | { 24 | get; 25 | private set; 26 | } 27 | 28 | public ParserRuleContext ParsingContext 29 | { 30 | get; 31 | private set; 32 | } 33 | 34 | public Class ParentClass => Parent.ParentClass; 35 | 36 | public Statement(IChild parent, ParserRuleContext ruleContext) 37 | { 38 | this.Parent = parent; 39 | this.ParsingContext = ruleContext; 40 | } 41 | 42 | public override string ToString() 43 | { 44 | return string.Format("({0}) {1}", this.GetType().Name, ParsingContext.GetText()); 45 | } 46 | 47 | public abstract void GenerateBytecode(ClassesContainer container, ByteBlock context); 48 | 49 | public abstract void ValidateSemantics(SemanticsValidator validator); 50 | 51 | public abstract void ValidateTypes(SemanticsValidator validator); 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Nova.Bytecode/Symbols/SymbolTable.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.IO; 2 | using Nova.Utils.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Nova.Bytecode.Symbols 10 | { 11 | public class SymbolTable : IByteElement 12 | { 13 | private Dictionary m_table; 14 | 15 | public int Count 16 | { 17 | get 18 | { 19 | return m_table.Count; 20 | } 21 | } 22 | public SymbolTable() 23 | { 24 | this.m_table = new Dictionary(); 25 | } 26 | public Symbol GetSymbol(string name) 27 | { 28 | Symbol sym = null; 29 | 30 | if (m_table.TryGetValue(name, out sym)) 31 | { 32 | return sym; 33 | } 34 | else 35 | { 36 | return null; 37 | } 38 | } 39 | public int Bind(string name,string type) 40 | { 41 | int id = (m_table.Count - 1) + 1; 42 | m_table.Add(name, new Symbol(id, type)); 43 | return id; 44 | } 45 | public void Serialize(CppBinaryWriter writer) 46 | { 47 | writer.Write(m_table.Count); 48 | 49 | foreach (var symbol in m_table) 50 | { 51 | writer.Write(symbol.Key); 52 | symbol.Value.Serialize(writer); 53 | } 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Nova.Bytecode/IO/ByteField.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.ByteCode.Enums; 3 | using Nova.ByteCode.Generation; 4 | using Nova.Utils.IO; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace Nova.ByteCode.IO 13 | { 14 | /// 15 | /// Field static 16 | /// 17 | public class ByteField : IByteElement 18 | { 19 | public string Name 20 | { 21 | get; 22 | set; 23 | } 24 | private ByteBlock Meta 25 | { 26 | get; 27 | set; 28 | } 29 | public object Value 30 | { 31 | get; 32 | set; 33 | } 34 | public ByteClass ParentClass 35 | { 36 | get; 37 | set; 38 | } 39 | public ModifiersEnum Modifiers 40 | { 41 | get; 42 | private set; 43 | } 44 | public ByteField(ByteClass parentClass, ModifiersEnum modifiers, string name, ByteBlock meta) 45 | { 46 | this.ParentClass = parentClass; 47 | this.Name = name; 48 | this.Meta = meta; 49 | this.Modifiers = modifiers; 50 | } 51 | 52 | public void Serialize(CppBinaryWriter writer) 53 | { 54 | writer.Write(Name); 55 | writer.Write((byte)Modifiers); 56 | Meta.Serialize(writer); 57 | } 58 | 59 | 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Nova/Antlr/NovaLexer.tokens: -------------------------------------------------------------------------------- 1 | USING=1 2 | CLASS=2 3 | STRUCT=3 4 | PUBLIC=4 5 | PRIVATE=5 6 | PRIMITIVE=6 7 | UNIT=7 8 | DOUBLE=8 9 | FLOAT=9 10 | INT=10 11 | SHORT=11 12 | STRING=12 13 | BOOLEAN=13 14 | CHAR=14 15 | BYTE=15 16 | LONG=16 17 | FOR=17 18 | IF=18 19 | WHILE=19 20 | ELSE=20 21 | RETURN=21 22 | NEW=22 23 | NATIVE=23 24 | ASSIGN=24 25 | ADD=25 26 | SUB=26 27 | MUL=27 28 | DIV=28 29 | LE=29 30 | GE=30 31 | GT=31 32 | LT=32 33 | EQUAL=33 34 | NOTEQUAL=34 35 | AND=35 36 | OR=36 37 | LPAREN=37 38 | RPAREN=38 39 | LBRACE=39 40 | RBRACE=40 41 | LBRACK=41 42 | RBRACK=42 43 | COMMA=43 44 | DOT=44 45 | SEMI=45 46 | NULL_LITERAL=46 47 | BOOL_LITERAL=47 48 | IDENTIFIER=48 49 | WS=49 50 | COMMENT=50 51 | LINE_COMMENT=51 52 | DECIMAL_LITERAL=52 53 | HEX_LITERAL=53 54 | OCT_LITERAL=54 55 | BINARY_LITERAL=55 56 | FLOAT_LITERAL=56 57 | HEX_FLOAT_LITERAL=57 58 | CHAR_LITERAL=58 59 | STRING_LITERAL=59 60 | 'using'=1 61 | 'class'=2 62 | 'struct'=3 63 | 'public'=4 64 | 'private'=5 65 | 'primitive'=6 66 | 'unit'=7 67 | 'double'=8 68 | 'float'=9 69 | 'int'=10 70 | 'short'=11 71 | 'string'=12 72 | 'bool'=13 73 | 'char'=14 74 | 'byte'=15 75 | 'long'=16 76 | 'for'=17 77 | 'if'=18 78 | 'while'=19 79 | 'else'=20 80 | 'return'=21 81 | '->'=22 82 | '~'=23 83 | '='=24 84 | '+'=25 85 | '-'=26 86 | '*'=27 87 | '/'=28 88 | '<='=29 89 | '>='=30 90 | '>'=31 91 | '<'=32 92 | '=='=33 93 | '!='=34 94 | '&&'=35 95 | '||'=36 96 | '('=37 97 | ')'=38 98 | '{'=39 99 | '}'=40 100 | '['=41 101 | ']'=42 102 | ','=43 103 | '.'=44 104 | ';'=45 105 | 'null'=46 106 | -------------------------------------------------------------------------------- /Nova/Antlr/NovaParser.tokens: -------------------------------------------------------------------------------- 1 | USING=1 2 | CLASS=2 3 | STRUCT=3 4 | PUBLIC=4 5 | PRIVATE=5 6 | PRIMITIVE=6 7 | UNIT=7 8 | DOUBLE=8 9 | FLOAT=9 10 | INT=10 11 | SHORT=11 12 | STRING=12 13 | BOOLEAN=13 14 | CHAR=14 15 | BYTE=15 16 | LONG=16 17 | FOR=17 18 | IF=18 19 | WHILE=19 20 | ELSE=20 21 | RETURN=21 22 | NEW=22 23 | NATIVE=23 24 | ASSIGN=24 25 | ADD=25 26 | SUB=26 27 | MUL=27 28 | DIV=28 29 | LE=29 30 | GE=30 31 | GT=31 32 | LT=32 33 | EQUAL=33 34 | NOTEQUAL=34 35 | AND=35 36 | OR=36 37 | LPAREN=37 38 | RPAREN=38 39 | LBRACE=39 40 | RBRACE=40 41 | LBRACK=41 42 | RBRACK=42 43 | COMMA=43 44 | DOT=44 45 | SEMI=45 46 | NULL_LITERAL=46 47 | BOOL_LITERAL=47 48 | IDENTIFIER=48 49 | WS=49 50 | COMMENT=50 51 | LINE_COMMENT=51 52 | DECIMAL_LITERAL=52 53 | HEX_LITERAL=53 54 | OCT_LITERAL=54 55 | BINARY_LITERAL=55 56 | FLOAT_LITERAL=56 57 | HEX_FLOAT_LITERAL=57 58 | CHAR_LITERAL=58 59 | STRING_LITERAL=59 60 | 'using'=1 61 | 'class'=2 62 | 'struct'=3 63 | 'public'=4 64 | 'private'=5 65 | 'primitive'=6 66 | 'unit'=7 67 | 'double'=8 68 | 'float'=9 69 | 'int'=10 70 | 'short'=11 71 | 'string'=12 72 | 'bool'=13 73 | 'char'=14 74 | 'byte'=15 75 | 'long'=16 76 | 'for'=17 77 | 'if'=18 78 | 'while'=19 79 | 'else'=20 80 | 'return'=21 81 | '->'=22 82 | '~'=23 83 | '='=24 84 | '+'=25 85 | '-'=26 86 | '*'=27 87 | '/'=28 88 | '<='=29 89 | '>='=30 90 | '>'=31 91 | '<'=32 92 | '=='=33 93 | '!='=34 94 | '&&'=35 95 | '||'=36 96 | '('=37 97 | ')'=38 98 | '{'=39 99 | '}'=40 100 | '['=41 101 | ']'=42 102 | ','=43 103 | '.'=44 104 | ';'=45 105 | 'null'=46 106 | -------------------------------------------------------------------------------- /Nova/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Les informations générales relatives à un assembly dépendent de 6 | // l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations 7 | // associées à un assembly. 8 | [assembly: AssemblyTitle("Nova")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Nova")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly 18 | // aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de 19 | // COM, affectez la valeur true à l'attribut ComVisible sur ce type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM 23 | [assembly: Guid("8ef17b2e-af37-444c-b2c0-3b6099321bd7")] 24 | 25 | // Les informations de version pour un assembly se composent des quatre valeurs suivantes : 26 | // 27 | // Version principale 28 | // Version secondaire 29 | // Numéro de build 30 | // Révision 31 | // 32 | // Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut 33 | // en utilisant '*', comme indiqué ci-dessous : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Nova.Antlr/AntlrTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.Antlr 9 | { 10 | public class AntlrTool 11 | { 12 | public const string DLanguage = "CSharp_v4_5"; 13 | 14 | public const string AntlrNamespace = "org.antlr.v4.Tool"; 15 | 16 | private string AntlrPath 17 | { 18 | get; 19 | set; 20 | } 21 | public AntlrTool(string antlrPath) 22 | { 23 | this.AntlrPath = antlrPath; 24 | } 25 | public bool Generate(string grammarPath, string outputDirectory) 26 | { 27 | ProcessStartInfo psi = new ProcessStartInfo("java", string.Format("-cp {0} {1} -Dlanguage={2} {3} -o {4}", AntlrPath, AntlrNamespace, DLanguage, grammarPath, outputDirectory)); 28 | Process process = new Process(); 29 | process.StartInfo = psi; 30 | process.StartInfo.UseShellExecute = false; 31 | process.StartInfo.RedirectStandardOutput = true; 32 | process.OutputDataReceived += Process_OutputDataReceived; 33 | process.Start(); 34 | process.BeginOutputReadLine(); 35 | process.WaitForExit(); 36 | return process.ExitCode == 0; 37 | } 38 | 39 | private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) 40 | { 41 | if (!string.IsNullOrWhiteSpace(e.Data)) 42 | Console.WriteLine(e.Data); 43 | } 44 | 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Nova/Expressions/VariableNameExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.Bytecode.Codes; 3 | using Nova.Bytecode.Symbols; 4 | using Nova.ByteCode.Codes; 5 | using Nova.ByteCode.Generation; 6 | using Nova.IO; 7 | using Nova.Members; 8 | using Nova.Semantics; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using Nova.Lexer; 15 | using Nova.Bytecode.Enums; 16 | using Nova.Expressions.Accessors; 17 | 18 | namespace Nova.Expressions 19 | { 20 | public class VariableNameExpression : AccessorExpression 21 | { 22 | public override AccessorType AccessorType => AccessorType.Field; 23 | 24 | public AccessorTree Tree 25 | { 26 | get; 27 | private set; 28 | } 29 | public bool Store 30 | { 31 | get; 32 | set; 33 | } 34 | 35 | 36 | public VariableNameExpression(IChild parent, ParserRuleContext context) : base(parent, context) 37 | { 38 | 39 | } 40 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 41 | { 42 | Tree.GenerateBytecode(container, context); 43 | } 44 | 45 | 46 | public override void ValidateSemantics(SemanticsValidator validator) 47 | { 48 | this.Tree = new AccessorTree(this, Store); 49 | this.Tree.ValidateSemantics(validator); 50 | } 51 | public override string ToString() 52 | { 53 | return base.ToString() + " {" + Name + "}"; 54 | } 55 | 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Nova.Antlr/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Les informations générales relatives à un assembly dépendent de 6 | // l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations 7 | // associées à un assembly. 8 | [assembly: AssemblyTitle("Nova.Antlr")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Nova.Antlr")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly 18 | // aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de 19 | // COM, affectez la valeur true à l'attribut ComVisible sur ce type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM 23 | [assembly: Guid("0218b638-6ff7-4859-aa0d-0cdf4ab781f8")] 24 | 25 | // Les informations de version pour un assembly se composent des quatre valeurs suivantes : 26 | // 27 | // Version principale 28 | // Version secondaire 29 | // Numéro de build 30 | // Révision 31 | // 32 | // Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut 33 | // en utilisant '*', comme indiqué ci-dessous : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Nova.Utils/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Les informations générales relatives à un assembly dépendent de 6 | // l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations 7 | // associées à un assembly. 8 | [assembly: AssemblyTitle("Nova.Utils")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Nova.Utils")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly 18 | // aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de 19 | // COM, affectez la valeur true à l'attribut ComVisible sur ce type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM 23 | [assembly: Guid("7350e0c1-89ba-49ca-a71f-635916446c35")] 24 | 25 | // Les informations de version pour un assembly se composent des quatre valeurs suivantes : 26 | // 27 | // Version principale 28 | // Version secondaire 29 | // Numéro de build 30 | // Révision 31 | // 32 | // Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut 33 | // en utilisant '*', comme indiqué ci-dessous : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Nova.Bytecode/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Les informations générales relatives à un assembly dépendent de 6 | // l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations 7 | // associées à un assembly. 8 | [assembly: AssemblyTitle("Nova.Bytecode")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Nova.Bytecode")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly 18 | // aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de 19 | // COM, affectez la valeur true à l'attribut ComVisible sur ce type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM 23 | [assembly: Guid("938e11e6-2ace-445a-bdf0-14715e209e6d")] 24 | 25 | // Les informations de version pour un assembly se composent des quatre valeurs suivantes : 26 | // 27 | // Version principale 28 | // Version secondaire 29 | // Numéro de build 30 | // Révision 31 | // 32 | // Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut 33 | // en utilisant '*', comme indiqué ci-dessous : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Nova.Compiler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Les informations générales relatives à un assembly dépendent de 6 | // l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations 7 | // associées à un assembly. 8 | [assembly: AssemblyTitle("Nova.Builder")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Nova.Builder")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly 18 | // aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de 19 | // COM, affectez la valeur true à l'attribut ComVisible sur ce type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM 23 | [assembly: Guid("02d71f87-48c5-4ee2-83cb-3ffd8b79e877")] 24 | 25 | // Les informations de version pour un assembly se composent des quatre valeurs suivantes : 26 | // 27 | // Version principale 28 | // Version secondaire 29 | // Numéro de build 30 | // Révision 31 | // 32 | // Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut 33 | // en utilisant '*', comme indiqué ci-dessous : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Nova/Members/Variable.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.IO; 3 | using Nova.Semantics; 4 | using Nova.Types; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace Nova.Members 13 | { 14 | public class Variable : IAccessible 15 | { 16 | public string Name 17 | { 18 | get; 19 | set; 20 | } 21 | public string RawType 22 | { 23 | get; 24 | set; 25 | } 26 | public NovaType Type 27 | { 28 | get; 29 | set; 30 | } 31 | private ParserRuleContext Context 32 | { 33 | get; 34 | set; 35 | } 36 | public Variable(string name, string type, ParserRuleContext context) 37 | { 38 | this.Name = name; 39 | this.RawType = type; 40 | this.Context = context; 41 | } 42 | 43 | public void ValidateTypes(SemanticsValidator validator) 44 | { 45 | this.Type = validator.Container.TypeManager.GetTypeInstance(RawType); 46 | 47 | if (this.Type == null) 48 | { 49 | validator.AddError("Unknown variable type " + RawType, Context); 50 | } 51 | 52 | } 53 | 54 | public override string ToString() 55 | { 56 | return RawType + " " + Name; 57 | } 58 | 59 | public Class GetContextualClass(SemanticsValidator validator) 60 | { 61 | return Type != null ? Type.Class : null; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Nova.Bytecode/IO/Symbol.cs: -------------------------------------------------------------------------------- 1 | using Nova.Utils.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Nova.Bytecode.IO 9 | { 10 | public class Symbol 11 | { 12 | public int Id; 13 | 14 | public Symbol(int id) 15 | { 16 | this.Id = id; 17 | } 18 | public void Serialize(CppBinaryWriter writer) 19 | { 20 | writer.Write(Id); 21 | } 22 | } 23 | public class SymbolTable 24 | { 25 | private Dictionary Symbols 26 | { 27 | get; 28 | set; 29 | } 30 | 31 | public SymbolTable() 32 | { 33 | this.Symbols = new Dictionary(); 34 | } 35 | 36 | public int BindVariable(string name) 37 | { 38 | int id = (Symbols.Count - 1) + 1; 39 | Symbols.Add(name, new Symbol(id)); 40 | return id; 41 | } 42 | public int GetVariableId(string name) 43 | { 44 | Symbol sym = null; 45 | 46 | if (Symbols.TryGetValue(name, out sym)) 47 | { 48 | return sym.Id; 49 | } 50 | else 51 | { 52 | return -1; 53 | } 54 | } 55 | public void Serialize(CppBinaryWriter writer) 56 | { 57 | writer.Write(Symbols.Count); 58 | 59 | foreach (var pair in Symbols) 60 | { 61 | writer.Write(pair.Key); 62 | pair.Value.Serialize(writer); 63 | } 64 | } 65 | 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Nova/Statements/DeclarationStatement.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.ByteCode.Generation; 3 | using Nova.Lexer; 4 | using Nova.IO; 5 | using Nova.Members; 6 | using Nova.Semantics; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Text.RegularExpressions; 13 | using System.Threading.Tasks; 14 | using Antlr4.Runtime; 15 | 16 | namespace Nova.Statements 17 | { 18 | public class DeclarationStatement : Statement 19 | { 20 | public Variable Variable 21 | { 22 | get; 23 | set; 24 | } 25 | public ExpressionNode Value 26 | { 27 | get; 28 | set; 29 | } 30 | public DeclarationStatement(IChild parent, ParserRuleContext context) : base(parent, context) 31 | { 32 | 33 | } 34 | 35 | 36 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 37 | { 38 | List results = new List(); 39 | 40 | int variableId = context.SymbolTable.Bind(Variable.Name, Variable.RawType); 41 | 42 | Value.GenerateBytecode(container, context); 43 | context.Instructions.Add(new StoreCode(variableId)); 44 | } 45 | 46 | public override void ValidateSemantics(SemanticsValidator validator) 47 | { 48 | Value.ValidateSemantics(validator); 49 | validator.DeclareVariable(Variable); 50 | 51 | } 52 | 53 | public override void ValidateTypes(SemanticsValidator validator) 54 | { 55 | Variable.ValidateTypes(validator); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Nova/Statements/ExpressionStatement.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.ByteCode.Generation; 3 | using Nova.Expressions; 4 | using Nova.IO; 5 | using Nova.Lexer; 6 | using Nova.Members; 7 | using Nova.Semantics; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Net; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | 15 | namespace Nova.Statements 16 | { 17 | public class ExpressionStatement : Statement 18 | { 19 | public ExpressionNode Expression 20 | { 21 | get; 22 | set; 23 | } 24 | public ExpressionStatement(IChild parent, ParserRuleContext ruleContext) : base(parent, ruleContext) 25 | { 26 | 27 | } 28 | 29 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 30 | { 31 | Expression.GenerateBytecode(container, context); 32 | } 33 | 34 | public override void ValidateSemantics(SemanticsValidator validator) 35 | { 36 | var tree = Expression.GetTree(); 37 | 38 | foreach (var expr in tree) 39 | { 40 | if (expr is not MethodCallExpression && expr is not NativeCallExpression && expr is not VariableNameExpression) 41 | { 42 | validator.AddError("Forbidenn expression statement (" + expr.GetType().Name + ")", base.ParsingContext); 43 | return; 44 | } 45 | } 46 | 47 | 48 | Expression.ValidateSemantics(validator); 49 | } 50 | 51 | public override void ValidateTypes(SemanticsValidator validator) 52 | { 53 | 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Nova/Statements/AssignationStatement.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.ByteCode.Generation; 3 | using Nova.Lexer; 4 | using Nova.IO; 5 | using Nova.Members; 6 | using Nova.Semantics; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Text.RegularExpressions; 13 | using System.Threading.Tasks; 14 | using Nova.Bytecode.Codes; 15 | using Nova.Bytecode.Enums; 16 | using Nova.Bytecode.Symbols; 17 | using Antlr4.Runtime; 18 | using Nova.Expressions; 19 | 20 | namespace Nova.Statements 21 | { 22 | public class AssignationStatement : Statement 23 | { 24 | public VariableNameExpression Target 25 | { 26 | get; 27 | set; 28 | } 29 | 30 | public char Operator 31 | { 32 | get; 33 | set; 34 | } 35 | public ExpressionNode Value 36 | { 37 | get; 38 | set; 39 | } 40 | 41 | public AssignationStatement(IChild parent, ParserRuleContext context) : base(parent, context) 42 | { 43 | 44 | } 45 | 46 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 47 | { 48 | Value.GenerateBytecode(container, context); 49 | 50 | Target.GenerateBytecode(container, context); 51 | 52 | } 53 | 54 | public override void ValidateSemantics(SemanticsValidator validator) 55 | { 56 | Target.Store = true; 57 | 58 | Value.ValidateSemantics(validator); 59 | 60 | Target.ValidateSemantics(validator); 61 | 62 | } 63 | 64 | public override void ValidateTypes(SemanticsValidator validator) 65 | { 66 | 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Nova.Bytecode/IO/ByteClass.cs: -------------------------------------------------------------------------------- 1 | using Nova.Bytecode.Enums; 2 | using Nova.Bytecode.Symbols; 3 | using Nova.Utils.IO; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace Nova.ByteCode.IO 12 | { 13 | public class ByteClass : IByteElement 14 | { 15 | public string Name 16 | { 17 | get; 18 | private set; 19 | } 20 | public ContainerType Type 21 | { 22 | get; 23 | private set; 24 | } 25 | public List Methods 26 | { 27 | get; 28 | set; 29 | } 30 | 31 | public List Fields 32 | { 33 | get; 34 | set; 35 | } 36 | 37 | public NovFile NovFile 38 | { 39 | get; 40 | private set; 41 | } 42 | 43 | public ByteClass(NovFile file, string name, ContainerType type) 44 | { 45 | this.NovFile = file; 46 | this.Name = name; 47 | this.Type = type; 48 | this.Methods = new List(); 49 | this.Fields = new List(); 50 | } 51 | 52 | 53 | public void Serialize(CppBinaryWriter writer) 54 | { 55 | writer.Write(Name); 56 | 57 | writer.Write((byte)Type); 58 | 59 | writer.Write(Methods.Count); 60 | 61 | foreach (var method in Methods) 62 | { 63 | method.Serialize(writer); 64 | } 65 | 66 | writer.Write(Fields.Count); 67 | 68 | foreach (var field in Fields) 69 | { 70 | field.Serialize(writer); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Nova/Statements/VectorCreationStatement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | using Antlr4.Runtime; 8 | using Nova.Bytecode.Codes; 9 | using Nova.ByteCode.Generation; 10 | using Nova.IO; 11 | using Nova.Lexer; 12 | using Nova.Members; 13 | using Nova.Semantics; 14 | 15 | namespace Nova.Statements 16 | { 17 | public class VectorCreationStatement : Statement 18 | { 19 | private List Elements 20 | { 21 | get; 22 | set; 23 | } 24 | 25 | public VectorCreationStatement(IChild parent, List elements, ParserRuleContext context) : base(parent, context) 26 | { 27 | this.Elements = elements; 28 | } 29 | 30 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 31 | { 32 | Class targetClass = container.TryGetClass(Constants.STDVectorClassName); 33 | 34 | context.Instructions.Add(new StructCreateCode(container.GetClassId(Constants.STDVectorClassName))); 35 | 36 | foreach (var element in Elements) 37 | { 38 | element.GenerateBytecode(container, context); 39 | } 40 | 41 | context.Instructions.Add(new VectCreateCode(Elements.Count)); 42 | 43 | context.Instructions.Add(new CtorCallCode(targetClass.GetCtor().Id, 1)); 44 | } 45 | 46 | public override void ValidateSemantics(SemanticsValidator validator) 47 | { 48 | foreach (var element in Elements) 49 | { 50 | element.ValidateSemantics(validator); 51 | } 52 | } 53 | 54 | public override void ValidateTypes(SemanticsValidator validator) 55 | { 56 | 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Nova.Bytecode/IO/ByteMethod.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.ByteCode.Enums; 3 | using Nova.ByteCode.Generation; 4 | using Nova.Utils; 5 | using Nova.Utils.IO; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace Nova.ByteCode.IO 14 | { 15 | public class ByteMethod : IByteElement 16 | { 17 | public string Name 18 | { 19 | get; 20 | set; 21 | } 22 | public ByteBlock ByteBlock 23 | { 24 | get; 25 | set; 26 | } 27 | public ByteClass ParentClass 28 | { 29 | get; 30 | set; 31 | } 32 | public ModifiersEnum Modifiers 33 | { 34 | get; 35 | set; 36 | } 37 | public int ParametersCount 38 | { 39 | get; 40 | set; 41 | } 42 | public ByteMethod(string name, ModifiersEnum modifiers, int parametersCount, ByteClass parentClass) 43 | { 44 | this.Name = name; 45 | this.Modifiers = modifiers; 46 | this.ByteBlock = new ByteBlock(parentClass); 47 | this.ParentClass = parentClass; 48 | this.ParametersCount = parametersCount; 49 | } 50 | public void Print() 51 | { 52 | Logger.Write("-------" + ToString() + " bytecode--------", LogType.Color2); 53 | ByteBlock.Print(); 54 | Logger.Write("-------" + ToString() + " bytecode--------", LogType.Color2); 55 | } 56 | public override string ToString() 57 | { 58 | return Name + "()"; 59 | } 60 | public void Serialize(CppBinaryWriter writer) 61 | { 62 | writer.Write(Name); 63 | writer.Write((byte)Modifiers); 64 | writer.Write(ParametersCount); 65 | ByteBlock.Serialize(writer); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Nova/Expressions/NativeCallExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.Bytecode.Enums; 3 | using Nova.ByteCode.Codes; 4 | using Nova.ByteCode.Generation; 5 | using Nova.IO; 6 | using Nova.Lexer; 7 | using Nova.Members; 8 | using Nova.Semantics; 9 | using Nova.Statements; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Linq; 13 | using System.Text; 14 | using System.Threading.Tasks; 15 | 16 | namespace Nova.Expressions 17 | { 18 | public class NativeCallExpression : Expression 19 | { 20 | private string NativeName 21 | { 22 | get; 23 | set; 24 | } 25 | public List Parameters 26 | { 27 | get; 28 | set; 29 | } 30 | private NativesEnum NativeEnum 31 | { 32 | get; 33 | set; 34 | } 35 | public NativeCallExpression(IChild parent, string nativeName, ParserRuleContext context) : base(parent, context) 36 | { 37 | this.NativeName = nativeName; 38 | this.NativeName = nativeName; 39 | } 40 | 41 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 42 | { 43 | foreach (var parameter in Parameters) 44 | { 45 | parameter.GenerateBytecode(container, context); 46 | } 47 | 48 | context.Instructions.Add(new NativeCallCode((int)NativeEnum)); 49 | 50 | } 51 | 52 | public override void ValidateSemantics(SemanticsValidator validator) 53 | { 54 | NativesEnum result = NativesEnum.Unknown; 55 | 56 | if (!Enum.TryParse(NativeName, out result) || result == NativesEnum.Unknown) 57 | { 58 | validator.AddError("Unknown native function : " + NativeName, ParsingContext); 59 | } 60 | 61 | NativeEnum = result; 62 | foreach (var parameter in Parameters) 63 | { 64 | parameter.ValidateSemantics(validator); 65 | } 66 | } 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Nova/Statements/WhileStatement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Threading.Tasks; 8 | using Nova.Bytecode.Codes; 9 | using Nova.ByteCode.Codes; 10 | using Nova.ByteCode.Generation; 11 | using Nova.Lexer; 12 | using Nova.IO; 13 | using Nova.Members; 14 | using Nova.Semantics; 15 | using Antlr4.Runtime; 16 | 17 | namespace Nova.Statements 18 | { 19 | public class WhileStatement : Statement 20 | { 21 | public ExpressionNode Condition 22 | { 23 | get; 24 | set; 25 | } 26 | public List Statements 27 | { 28 | get; 29 | set; 30 | } 31 | 32 | public WhileStatement(IChild parent, ParserRuleContext context) : base(parent, context) 33 | { 34 | 35 | 36 | 37 | } 38 | 39 | 40 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 41 | { 42 | int jumpIndex = context.NextOpIndex; 43 | 44 | Condition.GenerateBytecode(container, context); 45 | 46 | JumpIfFalseCode jumpIfFalse = new JumpIfFalseCode(-1); 47 | 48 | context.Instructions.Add(jumpIfFalse); 49 | 50 | foreach (var statement in Statements) 51 | { 52 | statement.GenerateBytecode(container, context); 53 | } 54 | 55 | context.Instructions.Add(new JumpCode(jumpIndex)); 56 | 57 | jumpIfFalse.targetIndex = context.NextOpIndex; 58 | 59 | } 60 | 61 | public override void ValidateSemantics(SemanticsValidator validator) 62 | { 63 | Condition.ValidateSemantics(validator); 64 | 65 | validator.BlockStart(); 66 | 67 | foreach (var statement in Statements) 68 | { 69 | statement.ValidateSemantics(validator); 70 | } 71 | 72 | validator.BlockEnd(); 73 | } 74 | 75 | public override void ValidateTypes(SemanticsValidator validator) 76 | { 77 | 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Nova.Compiler/Program.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode; 2 | using Nova.ByteCode.Generation; 3 | using Nova.IO; 4 | using Nova.Lexer; 5 | using Nova.Utils; 6 | using Nova.Utils.IO; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Diagnostics; 10 | using System.IO; 11 | using System.Linq; 12 | using System.Reflection; 13 | using System.Text; 14 | using System.Text.RegularExpressions; 15 | using System.Threading.Tasks; 16 | 17 | 18 | namespace Nova.Compiler 19 | { 20 | class Program 21 | { 22 | static void Main(string[] args) 23 | { 24 | Console.Title = Assembly.GetCallingAssembly().GetName().Name; 25 | 26 | if (args.Length == 0) 27 | { 28 | Logger.Write("You need to specify a nova file (.nv).", LogType.Warning); 29 | Console.Read(); 30 | return; 31 | } 32 | if (args.Length > 2) 33 | { 34 | Logger.Write("Args are [scriptPath] [outputPath]?"); 35 | Console.Read(); 36 | return; 37 | } 38 | 39 | bool outputPathSpecified = args.Length == 2; 40 | 41 | string outputPath; 42 | 43 | if (outputPathSpecified) 44 | { 45 | outputPath = args[1]; 46 | Logger.Write("Output path specified : " + outputPath, LogType.Debug); 47 | 48 | } 49 | else 50 | { 51 | Logger.Write("Using default ouput path : " + Constants.DefaultOuputPath, LogType.Debug); 52 | outputPath = Constants.DefaultOuputPath; 53 | } 54 | 55 | Stopwatch st = Stopwatch.StartNew(); 56 | 57 | NovBuilder builder = new NovBuilder(args[0], outputPath); 58 | 59 | if (!builder.Build()) 60 | { 61 | Console.Read(); 62 | return; 63 | } 64 | 65 | builder.Save(); 66 | 67 | Logger.Write(outputPath + " generated in " + st.ElapsedMilliseconds + "ms", LogType.Debug); 68 | 69 | builder.PrintMainByteCode(); 70 | 71 | Console.Read(); 72 | 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Nova.Bytecode/Generation/ByteBlock.cs: -------------------------------------------------------------------------------- 1 | using Nova.Bytecode.Symbols; 2 | using Nova.ByteCode.Codes; 3 | using Nova.ByteCode.IO; 4 | using Nova.Utils; 5 | using Nova.Utils.IO; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace Nova.ByteCode.Generation 14 | { 15 | public class ByteBlock : IByteElement 16 | { 17 | public SymbolTable SymbolTable 18 | { 19 | get; 20 | private set; 21 | } 22 | public List Instructions 23 | { 24 | get; 25 | set; 26 | } 27 | public int NextOpIndex 28 | { 29 | get 30 | { 31 | return Instructions.Sum(x => x.GetSize() + 1); 32 | } 33 | } 34 | public int LocalsCount 35 | { 36 | get 37 | { 38 | return SymbolTable.Count; 39 | } 40 | } 41 | public ByteClass ParentClass 42 | { 43 | get; 44 | private set; 45 | } 46 | public ByteBlock(ByteClass parentClass) 47 | { 48 | this.SymbolTable = new SymbolTable(); 49 | this.Instructions = new List(); 50 | this.ParentClass = parentClass; 51 | } 52 | 53 | public void Print() 54 | { 55 | foreach (var byteCode in Instructions) 56 | { 57 | Logger.Write(byteCode); 58 | } 59 | } 60 | 61 | public int BindConstant(object value) 62 | { 63 | return ParentClass.NovFile.BindConstant(value); 64 | } 65 | 66 | public void Serialize(CppBinaryWriter writer) 67 | { 68 | //SymbolTable.Serialize(writer); 69 | 70 | int size = Instructions.Sum(x => x.GetSize() + 1); 71 | 72 | writer.Write(size); 73 | 74 | foreach (var code in Instructions) 75 | { 76 | writer.Write(code.OpId); 77 | code.Serialize(writer); 78 | } 79 | 80 | writer.Write(LocalsCount); 81 | } 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Nova/Parser/Listeners/ClassListener.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime.Misc; 2 | using Antlr4.Runtime.Tree; 3 | using Nova.Bytecode.Enums; 4 | using Nova.IO; 5 | using Nova.Members; 6 | using System; 7 | using static NovaParser; 8 | using IErrorNode = Antlr4.Runtime.Tree.IErrorNode; 9 | using ITerminalNode = Antlr4.Runtime.Tree.ITerminalNode; 10 | using IToken = Antlr4.Runtime.IToken; 11 | using ParserRuleContext = Antlr4.Runtime.ParserRuleContext; 12 | 13 | namespace Nova.Parser.Listeners 14 | { 15 | public partial class ClassListener : NovaParserBaseListener 16 | { 17 | private NvFile File 18 | { 19 | get; 20 | set; 21 | } 22 | public ClassListener(NvFile file) 23 | { 24 | this.File = file; 25 | } 26 | 27 | public override void EnterTypeDeclaration([NotNull] TypeDeclarationContext context) 28 | { 29 | foreach (var rule in context.GetRuleContexts()) 30 | { 31 | rule.EnterRule(this); 32 | } 33 | } 34 | public override void EnterPrimitiveDeclaration([NotNull] PrimitiveDeclarationContext context) 35 | { 36 | string name = context.primitiveTypeOrUnit().GetText(); 37 | AddMember(name, ContainerType.primitive, context); 38 | } 39 | public override void EnterClassDeclaration(NovaParser.ClassDeclarationContext context) 40 | { 41 | string name = context.IDENTIFIER().GetText(); 42 | AddMember(name, ContainerType.@class, context); 43 | } 44 | public override void EnterStructDeclaration([NotNull] NovaParser.StructDeclarationContext context) 45 | { 46 | AddMember(context.IDENTIFIER().GetText(), ContainerType.@struct, context); 47 | } 48 | 49 | private void AddMember(string className, ContainerType type, ParserRuleContext context) 50 | { 51 | Class @class = new Class(File, className, type, context); 52 | ClassMemberListener listener = new ClassMemberListener(@class); 53 | 54 | foreach (var memberDeclaration in context.GetRuleContext(0).GetRuleContexts()) 55 | { 56 | memberDeclaration.EnterRule(listener); 57 | } 58 | 59 | File.Classes.Add(@class); 60 | } 61 | 62 | 63 | } 64 | } -------------------------------------------------------------------------------- /Nova.Utils/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Nova.Utils 8 | { 9 | public enum LogType 10 | { 11 | None = -1, 12 | Log = 0, 13 | Debug = 1, 14 | SemanticError = 2, 15 | SyntaxicError = 3, 16 | Error = 5, 17 | LogImportant = 6, 18 | Success = 7, 19 | Warning = 8, 20 | ProgramOutput = 9, 21 | Color1, 22 | Color2, 23 | } 24 | public class Logger 25 | { 26 | private const ConsoleColor COLOR_1 = ConsoleColor.Magenta; 27 | private const ConsoleColor COLOR_2 = ConsoleColor.DarkMagenta; 28 | 29 | private static LogType[] NoPrefix = new LogType[] 30 | { 31 | LogType.None, 32 | LogType.Color1, 33 | LogType.Color2, 34 | }; 35 | private static Dictionary Colors = new Dictionary() 36 | { 37 | { LogType.None,ConsoleColor.Gray }, 38 | { LogType.Log, ConsoleColor.Gray }, 39 | { LogType.Debug, ConsoleColor.DarkGray }, 40 | { LogType.LogImportant, ConsoleColor.White }, 41 | 42 | { LogType.Error, ConsoleColor.Red }, 43 | { LogType.SemanticError, ConsoleColor.Red }, 44 | { LogType.SyntaxicError, ConsoleColor.Red }, 45 | 46 | { LogType.Warning, ConsoleColor.Yellow}, 47 | 48 | { LogType.Success, ConsoleColor.Green }, 49 | { LogType.ProgramOutput, ConsoleColor.Magenta }, 50 | 51 | { LogType.Color1, ConsoleColor.DarkMagenta }, 52 | { LogType.Color2, ConsoleColor.DarkMagenta } 53 | }; 54 | 55 | public static void Write(object value, LogType state = LogType.None) 56 | { 57 | if (!NoPrefix.Contains(state)) 58 | { 59 | Console.ForegroundColor = ConsoleColor.Gray; 60 | Console.Write(state + " > "); 61 | } 62 | 63 | WriteColored(value, Colors[state]); 64 | } 65 | private static void WriteColored(object value, ConsoleColor color) 66 | { 67 | Console.ForegroundColor = color; 68 | Console.WriteLine(value); 69 | } 70 | public static void NewLine() 71 | { 72 | Console.WriteLine(Environment.NewLine); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Nova/Statements/ForStatement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | using Antlr4.Runtime; 8 | using Nova.ByteCode.Codes; 9 | using Nova.ByteCode.Generation; 10 | using Nova.IO; 11 | using Nova.Lexer; 12 | using Nova.Members; 13 | using Nova.Semantics; 14 | 15 | namespace Nova.Statements 16 | { 17 | public class ForStatement : Statement 18 | { 19 | public Statement Init 20 | { 21 | get; 22 | set; 23 | } 24 | public ExpressionNode Condition 25 | { 26 | get; 27 | set; 28 | } 29 | public Statement Update 30 | { 31 | get; 32 | set; 33 | } 34 | public List Statements 35 | { 36 | get; 37 | set; 38 | } 39 | 40 | public ForStatement(IChild parent, ParserRuleContext context) : base(parent, context) 41 | { 42 | 43 | } 44 | 45 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 46 | { 47 | Init.GenerateBytecode(container, context); 48 | 49 | int jumpIndex = context.NextOpIndex; 50 | 51 | Condition.GenerateBytecode(container, context); 52 | 53 | JumpIfFalseCode code = new JumpIfFalseCode(-1); 54 | context.Instructions.Add(code); 55 | 56 | foreach (var statement in this.Statements) 57 | { 58 | statement.GenerateBytecode(container, context); 59 | } 60 | 61 | Update.GenerateBytecode(container, context); 62 | 63 | context.Instructions.Add(new JumpCode(jumpIndex)); 64 | code.targetIndex = context.NextOpIndex; 65 | 66 | 67 | 68 | 69 | } 70 | 71 | public override void ValidateSemantics(SemanticsValidator validator) 72 | { 73 | validator.BlockStart(); 74 | 75 | Init.ValidateSemantics(validator); 76 | Condition.ValidateSemantics(validator); 77 | Update.ValidateSemantics(validator); 78 | 79 | foreach (var statement in Statements) 80 | { 81 | statement.ValidateSemantics(validator); 82 | } 83 | 84 | validator.BlockEnd(); 85 | } 86 | 87 | public override void ValidateTypes(SemanticsValidator validator) 88 | { 89 | 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Nova.Bytecode/IO/NovFile.cs: -------------------------------------------------------------------------------- 1 | using Nova.Bytecode.IO; 2 | using Nova.Utils; 3 | using Nova.Utils.IO; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace Nova.ByteCode.IO 12 | { 13 | public class NovFile : IByteElement 14 | { 15 | public const string HEADER = "NovaEX"; 16 | 17 | public List ByteClasses 18 | { 19 | get; 20 | private set; 21 | } 22 | public MainPointEntry MainPointEntry 23 | { 24 | get; 25 | set; 26 | } 27 | private List ConstantsTable 28 | { 29 | get; 30 | set; 31 | } 32 | /// 33 | /// todo : referenced file (recursively) 34 | /// 35 | public NovFile() 36 | { 37 | this.ByteClasses = new List(); 38 | this.ConstantsTable = new List(); 39 | } 40 | 41 | public object GetConstant(int constantId) 42 | { 43 | return ConstantsTable[constantId]; 44 | } 45 | 46 | public int BindConstant(object constant) 47 | { 48 | ConstantsTable.Add(constant); 49 | return ConstantsTable.Count - 1; 50 | } 51 | public void Serialize(CppBinaryWriter writer) 52 | { 53 | writer.Write(HEADER); 54 | 55 | MainPointEntry.Serialize(writer); 56 | 57 | writer.Write(ByteClasses.Count); 58 | 59 | foreach (var pair in ByteClasses) 60 | { 61 | pair.Serialize(writer); 62 | } 63 | 64 | writer.Write(ConstantsTable.Count); 65 | 66 | foreach (var value in ConstantsTable) 67 | { 68 | if (value is string) 69 | { 70 | writer.Write(1); 71 | writer.Write(value.ToString()); 72 | } 73 | else if (value is bool) 74 | { 75 | writer.Write(2); 76 | writer.Write((bool)value); 77 | } 78 | else 79 | { 80 | throw new Exception("Unhandled constant serialization."); 81 | } 82 | } 83 | } 84 | public ByteMethod GetMainMethod() 85 | { 86 | return ByteClasses[MainPointEntry.ClassIndex].Methods[MainPointEntry.MethodIndex]; 87 | } 88 | 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Nova.Antlr/Nova.Antlr.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8} 8 | Exe 9 | Nova.Antlr 10 | Nova.Antlr 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Nova/IO/NvFile.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | using Nova.Bytecode.Enums; 4 | using Nova.Bytecode.Symbols; 5 | using Nova.ByteCode.Enums; 6 | using Nova.Members; 7 | using Nova.Parser; 8 | using Nova.Parser.Errors; 9 | using Nova.Parser.Listeners; 10 | using Nova.Utils; 11 | using System; 12 | using System.Collections.Generic; 13 | using System.IO; 14 | using System.Linq; 15 | using System.Text; 16 | using System.Text.RegularExpressions; 17 | using System.Threading.Tasks; 18 | 19 | namespace Nova.IO 20 | { 21 | public class NvFile 22 | { 23 | public string Filepath 24 | { 25 | get; 26 | private set; 27 | } 28 | public List Usings 29 | { 30 | get; 31 | private set; 32 | } 33 | public List Classes 34 | { 35 | get; 36 | private set; 37 | } 38 | public NvFile(string filePath) 39 | { 40 | this.Filepath = filePath; 41 | this.Usings = new List(); 42 | this.Classes = new List(); 43 | } 44 | 45 | public bool Read() 46 | { 47 | if (!File.Exists(Filepath)) 48 | { 49 | Logger.Write("File not found : " + Filepath, LogType.Error); 50 | return false; 51 | } 52 | string text = File.ReadAllText(Filepath); 53 | 54 | NovaParsingErrorHandler parsingErrorHandler = new NovaParsingErrorHandler(); 55 | 56 | var inputStream = new AntlrInputStream(text); 57 | var lexer = new NovaLexer(inputStream); 58 | lexer.RemoveErrorListener(ConsoleErrorListener.Instance); 59 | 60 | var commonTokenStream = new CommonTokenStream(lexer); 61 | var parser = new NovaParser(commonTokenStream); 62 | parser.RemoveErrorListener(ConsoleErrorListener.Instance); 63 | parser.AddErrorListener(parsingErrorHandler); 64 | 65 | NovaParser.CompilationUnitContext ectx = parser.compilationUnit(); 66 | 67 | foreach (var importDeclaration in ectx.importDeclaration()) 68 | { 69 | Usings.Add(new Using(UsingType.Ref, importDeclaration.fileName().GetText())); 70 | } 71 | ClassListener classListener = new ClassListener(this); 72 | 73 | foreach (var typeDeclaration in ectx.typeDeclaration()) 74 | { 75 | typeDeclaration.EnterRule(classListener); 76 | } 77 | 78 | //Console.WriteLine(ectx.ToStringTree(parser)); 79 | 80 | return parsingErrorHandler.ErrorsCount == 0; 81 | } 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Nova/Statements/IfStatement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Threading.Tasks; 8 | using Nova.ByteCode.Codes; 9 | using Nova.ByteCode.Generation; 10 | using Nova.Lexer; 11 | using Nova.IO; 12 | using Nova.Members; 13 | using Nova.Semantics; 14 | using Antlr4.Runtime; 15 | 16 | namespace Nova.Statements 17 | { 18 | public class IfStatement : Statement 19 | { 20 | public ExpressionNode IfCondition 21 | { 22 | get; 23 | set; 24 | } 25 | public List IfStatements 26 | { 27 | get; 28 | set; 29 | } 30 | public List ElseStatements 31 | { 32 | get; 33 | set; 34 | } 35 | 36 | public IfStatement(IChild parent, ParserRuleContext context) : base(parent, context) 37 | { 38 | 39 | } 40 | 41 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 42 | { 43 | int jumpIndex = context.NextOpIndex; 44 | 45 | IfCondition.GenerateBytecode(container, context); 46 | 47 | JumpIfFalseCode jumpIfFalse = new JumpIfFalseCode(-1); 48 | 49 | context.Instructions.Add(jumpIfFalse); 50 | 51 | foreach (var statement in IfStatements) 52 | { 53 | statement.GenerateBytecode(container, context); 54 | } 55 | 56 | JumpCode jumpElseIfTrue = new JumpCode(-1); 57 | context.Instructions.Add(jumpElseIfTrue); 58 | 59 | jumpIfFalse.targetIndex = context.NextOpIndex; 60 | 61 | if (ElseStatements != null) 62 | { 63 | foreach (var statement in ElseStatements) 64 | { 65 | statement.GenerateBytecode(container, context); 66 | } 67 | } 68 | 69 | jumpElseIfTrue.targetIndex = context.NextOpIndex; 70 | 71 | 72 | } 73 | 74 | public override void ValidateSemantics(SemanticsValidator validator) 75 | { 76 | IfCondition.ValidateSemantics(validator); 77 | 78 | foreach (var statement in IfStatements) 79 | { 80 | statement.ValidateSemantics(validator); 81 | } 82 | 83 | if (ElseStatements != null) 84 | { 85 | foreach (var st in ElseStatements) 86 | { 87 | st.ValidateSemantics(validator); 88 | } 89 | } 90 | } 91 | 92 | public override void ValidateTypes(SemanticsValidator validator) 93 | { 94 | 95 | } 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /Nova/Expressions/MethodCallExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.Bytecode.Codes; 3 | using Nova.Bytecode.Enums; 4 | using Nova.Bytecode.Symbols; 5 | using Nova.ByteCode.Codes; 6 | using Nova.ByteCode.Generation; 7 | using Nova.Expressions.Accessors; 8 | using Nova.IO; 9 | using Nova.Lexer; 10 | using Nova.Members; 11 | using Nova.Semantics; 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Linq; 15 | using System.Text; 16 | using System.Threading.Tasks; 17 | 18 | namespace Nova.Expressions 19 | { 20 | public class MethodCallExpression : AccessorExpression 21 | { 22 | public override AccessorType AccessorType => AccessorType.Method; 23 | 24 | private AccessorTree AccessorTree 25 | { 26 | get; 27 | set; 28 | } 29 | /// 30 | /// Paramètres passés a la méthodes (liste d'Lexer) 31 | /// Verifier qu'il s'agit bien de statement valide pour une methode. (ne retourne pas void). (analyse sémantique) 32 | /// 33 | public List Parameters 34 | { 35 | get; 36 | set; 37 | } 38 | 39 | public MethodCallExpression(IChild parent, ParserRuleContext context) : base(parent, context) 40 | { 41 | 42 | } 43 | 44 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 45 | { 46 | foreach (var parameter in Parameters) 47 | { 48 | parameter.GenerateBytecode(container, context); 49 | } 50 | AccessorTree.GenerateBytecode(container, context); 51 | } 52 | 53 | public override void ValidateSemantics(SemanticsValidator validator) // methode accessible, nombre de parametres corrects. 54 | { 55 | foreach (var parameter in Parameters) 56 | { 57 | parameter.ValidateSemantics(validator); 58 | } 59 | 60 | AccessorTree = new AccessorTree(this, false); 61 | AccessorTree.ValidateSemantics(validator); 62 | 63 | Method target = AccessorTree.Last().GetTarget(); 64 | 65 | int requiredParameters = target.Parameters.Count; 66 | 67 | if (target.ParentClass.Type == ContainerType.primitive) 68 | { 69 | requiredParameters = requiredParameters - 1; 70 | } 71 | 72 | if (requiredParameters != Parameters.Count) 73 | { 74 | validator.AddError(Name + "() require " + requiredParameters + " parameters, but " + Parameters.Count + " was given", base.ParsingContext); 75 | } 76 | } 77 | 78 | public override string ToString() 79 | { 80 | return base.ToString() + " {" + Name + "}"; 81 | } 82 | 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Nova/Expressions/ExpressionNode.cs: -------------------------------------------------------------------------------- 1 | using Nova.Bytecode.Codes; 2 | using Nova.ByteCode.Codes; 3 | using Nova.ByteCode.Generation; 4 | using Nova.Expressions; 5 | using Nova.IO; 6 | using Nova.Members; 7 | using Nova.Semantics; 8 | using Nova.Statements; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.IO; 12 | using System.Linq; 13 | using System.Text; 14 | using System.Threading.Tasks; 15 | 16 | namespace Nova.Lexer 17 | { 18 | /* 19 | * bad name 20 | */ 21 | public class ExpressionNode : IChild 22 | { 23 | /* 24 | * Postfix 25 | */ 26 | private List Tree 27 | { 28 | get; 29 | set; 30 | } 31 | public IChild Parent 32 | { 33 | get; 34 | private set; 35 | } 36 | 37 | public Class ParentClass => Parent.ParentClass; 38 | 39 | public bool Empty => Tree.Count == 0; 40 | 41 | public ExpressionNode(IChild parent, Expression value) 42 | { 43 | this.Parent = parent; 44 | Tree = new List() { value }; 45 | } 46 | 47 | public ExpressionNode(IChild parent) 48 | { 49 | this.Parent = parent; 50 | Tree = new List(); 51 | } 52 | 53 | public void GenerateBytecode(ClassesContainer container, ByteBlock context) 54 | { 55 | if (Empty) 56 | { 57 | context.Instructions.Add(new PushNullCode()); 58 | } 59 | else 60 | { 61 | int i = 0; 62 | 63 | while (i < Tree.Count) 64 | { 65 | Tree[i].GenerateBytecode(container, context); 66 | i++; 67 | } 68 | 69 | } 70 | } 71 | public void Insert(Expression expression) 72 | { 73 | this.Tree.Insert(0, expression); // postfix order 74 | } 75 | public bool ValidateSemantics(SemanticsValidator validator) 76 | { 77 | if (Empty) 78 | { 79 | return true; 80 | 81 | } 82 | foreach (var expression in Tree) 83 | { 84 | expression.ValidateSemantics(validator); 85 | } 86 | 87 | return true; 88 | } 89 | public T Get(int index) where T : Expression 90 | { 91 | return (T)Tree[index]; 92 | } 93 | public IEnumerable GetTree() 94 | { 95 | return this.Tree; 96 | } 97 | public override string ToString() 98 | { 99 | return "{ Size : " + Tree.Count + " }"; 100 | } 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /Nova/Semantics/SemanticsValidator.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.IO; 3 | using Nova.Lexer; 4 | 5 | using Nova.Members; 6 | using Nova.Types; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace Nova.Semantics 14 | { 15 | public class SemanticsValidator 16 | { 17 | private Dictionary> DeclaredVariables // 18 | { 19 | get; 20 | set; 21 | } 22 | public int Deepness 23 | { 24 | get; 25 | set; 26 | } 27 | private List Errors 28 | { 29 | get; 30 | set; 31 | } 32 | public ClassesContainer Container 33 | { 34 | get; 35 | private set; 36 | } 37 | private Class CurrentClass 38 | { 39 | get; 40 | set; 41 | } 42 | 43 | public SemanticsValidator(Class currentClass, ClassesContainer container) 44 | { 45 | this.CurrentClass = currentClass; 46 | this.Flush(); 47 | this.Errors = new List(); 48 | this.Container = container; 49 | } 50 | 51 | public void Flush() 52 | { 53 | this.Deepness = 0; 54 | this.DeclaredVariables = new Dictionary>(); 55 | this.DeclaredVariables.Add(0, new Dictionary()); 56 | } 57 | public void DeclareVariable(Variable variable) 58 | { 59 | DeclaredVariables[Deepness].Add(variable.Name, variable); 60 | } 61 | public void BlockStart() 62 | { 63 | Deepness++; 64 | DeclaredVariables.Add(Deepness, new Dictionary()); 65 | } 66 | public void BlockEnd() 67 | { 68 | DeclaredVariables.Remove(Deepness); 69 | Deepness--; 70 | } 71 | public bool IsLocalDeclared(string name) 72 | { 73 | return GetLocal(name) != null; 74 | } 75 | public Variable GetLocal(string name) 76 | { 77 | for (int i = 0; i <= Deepness; i++) 78 | { 79 | if (DeclaredVariables[i].ContainsKey(name)) 80 | { 81 | return DeclaredVariables[i][name]; 82 | } 83 | } 84 | return null; 85 | } 86 | public void AddError(string message, ParserRuleContext context) 87 | { 88 | this.Errors.Add(new SemanticalError(CurrentClass.File.Filepath, message, context)); 89 | } 90 | public IEnumerable GetErrors() 91 | { 92 | return Errors; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Nova.Utils/Nova.Utils.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {7350E0C1-89BA-49CA-A71F-635916446C35} 8 | Library 9 | Properties 10 | Nova.Utils 11 | Nova.Utils 12 | v4.7.1 13 | 512 14 | true 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | x64 36 | bin\x64\Debug\ 37 | 38 | 39 | x64 40 | bin\x64\Release\ 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Nova/Members/Field.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Generation; 2 | using Nova.ByteCode.IO; 3 | using Nova.Lexer; 4 | using Nova.IO; 5 | using Nova.Statements; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using Nova.Semantics; 13 | using Nova.ByteCode.Enums; 14 | using Antlr4.Runtime; 15 | using Nova.Types; 16 | 17 | namespace Nova.Members 18 | { 19 | public class Field : IChild, IByteData, IAccessible 20 | { 21 | public Class ParentClass 22 | { 23 | get; 24 | private set; 25 | } 26 | public string Name 27 | { 28 | get 29 | { 30 | return Variable.Name; 31 | } 32 | } 33 | public int Id 34 | { 35 | get; 36 | set; 37 | } 38 | public string Type /* Validate type is a struct. Cannot be class ! */ 39 | { 40 | get 41 | { 42 | return Variable.RawType; 43 | } 44 | } 45 | public ModifiersEnum Modifiers 46 | { 47 | get; 48 | private set; 49 | } 50 | public Variable Variable 51 | { 52 | get; 53 | private set; 54 | } 55 | public ExpressionNode Value 56 | { 57 | get; 58 | set; 59 | } 60 | 61 | public IChild Parent => null; 62 | 63 | public Field(Class parentClass, int fieldId, ModifiersEnum modifiers, Variable variable) 64 | { 65 | this.Id = fieldId; 66 | this.ParentClass = parentClass; 67 | this.Modifiers = modifiers; 68 | this.Variable = variable; 69 | } 70 | public Field() 71 | { 72 | 73 | } 74 | 75 | public override string ToString() 76 | { 77 | return Modifiers + " " + Variable.RawType + " " + Variable.Name; 78 | } 79 | 80 | public IByteElement GetByteElement(ClassesContainer container, IByteElement parent) 81 | { 82 | ByteBlock meta = new ByteBlock((ByteClass)parent); 83 | Value.GenerateBytecode(container, meta); 84 | ByteField field = new ByteField((ByteClass)parent, Modifiers, Name, meta); 85 | return field; 86 | } 87 | 88 | public void ValidateSemantics(SemanticsValidator validator) 89 | { 90 | Value.ValidateSemantics(validator); 91 | } 92 | 93 | public Class GetContextualClass(SemanticsValidator validator) 94 | { 95 | return validator.Container.TryGetClass(Type); 96 | } 97 | 98 | public void ValidateTypes(SemanticsValidator validator) 99 | { 100 | Variable.ValidateTypes(validator); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Nova/Expressions/StructCallCtorStatement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Antlr4.Runtime; 7 | using Nova.Bytecode.Codes; 8 | using Nova.Bytecode.Enums; 9 | using Nova.ByteCode.Generation; 10 | using Nova.IO; 11 | using Nova.Lexer; 12 | using Nova.Members; 13 | using Nova.Semantics; 14 | 15 | namespace Nova.Expressions 16 | { 17 | public class StructCallCtorExpression : Expression 18 | { 19 | private string CtorName 20 | { 21 | get; 22 | set; 23 | } 24 | public List Parameters 25 | { 26 | get; 27 | set; 28 | } 29 | private Class StructClass 30 | { 31 | get; 32 | set; 33 | } 34 | private Method StructCtor 35 | { 36 | get; 37 | set; 38 | } 39 | 40 | public StructCallCtorExpression(IChild parent, string name, ParserRuleContext context) : base(parent, context) 41 | { 42 | this.CtorName = name; 43 | } 44 | 45 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 46 | { 47 | 48 | Class targetClass = container[CtorName]; 49 | 50 | context.Instructions.Add(new StructCreateCode(container.GetClassId(CtorName))); 51 | 52 | if (StructCtor != null) 53 | { 54 | foreach (var parameter in Parameters) 55 | { 56 | parameter.GenerateBytecode(container, context); 57 | } 58 | 59 | context.Instructions.Add(new CtorCallCode(targetClass.GetCtor().Id, Parameters.Count)); 60 | } 61 | } 62 | 63 | public override void ValidateSemantics(SemanticsValidator validator) 64 | { 65 | foreach (var parameter in Parameters) 66 | { 67 | parameter.ValidateSemantics(validator); 68 | } 69 | 70 | this.StructClass = validator.Container.TryGetClass(CtorName); 71 | 72 | if (StructClass == null) 73 | { 74 | validator.AddError("Unknown struct type " + CtorName, ParsingContext); 75 | } 76 | if (StructClass.Type != ContainerType.@struct) 77 | { 78 | validator.AddError("Constructors can only be called on struct", ParsingContext); 79 | } 80 | 81 | this.StructClass = validator.Container[CtorName]; 82 | 83 | this.StructCtor = StructClass.GetCtor(); 84 | 85 | if (StructCtor == null) 86 | { 87 | validator.AddError("Unknown struct ctor \"" + StructClass.ClassName + "\"", ParsingContext); 88 | } 89 | else if (Parameters.Count != StructCtor.Parameters.Count) 90 | { 91 | validator.AddError("Invalid parameters count for Ctor \"" + StructClass.ClassName + "\"", ParsingContext); 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Nova/Expressions/OperatorExpression.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Nova.Bytecode.Codes; 3 | using Nova.ByteCode.Codes; 4 | using Nova.ByteCode.Enums; 5 | using Nova.ByteCode.Generation; 6 | using Nova.IO; 7 | using Nova.Members; 8 | using Nova.Semantics; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | 15 | namespace Nova.Expressions 16 | { 17 | public class OperatorExpression : Expression 18 | { 19 | private static readonly Dictionary OPERATORS_BINDING = new Dictionary() 20 | { 21 | { "+",OperatorsEnum.Plus }, 22 | { "-",OperatorsEnum.Minus }, 23 | { "*",OperatorsEnum.Multiply }, 24 | { "/",OperatorsEnum.Divide }, 25 | { "==",OperatorsEnum.Equals }, 26 | { "!=",OperatorsEnum.Different }, 27 | { "<", OperatorsEnum.Inferior }, 28 | { ">",OperatorsEnum.Superior }, 29 | }; 30 | 31 | public string Operator 32 | { 33 | get; 34 | private set; 35 | } 36 | public OperatorsEnum OperatorEnum 37 | { 38 | get 39 | { 40 | return OPERATORS_BINDING[Operator]; 41 | } 42 | } 43 | 44 | public OperatorExpression(IChild parent, string @operator, ParserRuleContext context) : base(parent, context) 45 | { 46 | this.Operator = @operator; 47 | } 48 | 49 | public override void GenerateBytecode(ClassesContainer container, ByteBlock context) 50 | { 51 | 52 | switch (OperatorEnum) 53 | { 54 | case OperatorsEnum.Plus: 55 | context.Instructions.Add(new AddCode()); 56 | break; 57 | case OperatorsEnum.Minus: 58 | context.Instructions.Add(new SubCode()); 59 | break; 60 | case OperatorsEnum.Multiply: 61 | context.Instructions.Add(new MulCode()); 62 | break; 63 | case OperatorsEnum.Divide: 64 | context.Instructions.Add(new DivCode()); 65 | break; 66 | case OperatorsEnum.Inferior: 67 | context.Instructions.Add(new ComparaisonCode(OperatorsEnum.Inferior)); 68 | break; 69 | case OperatorsEnum.Superior: 70 | context.Instructions.Add(new ComparaisonCode(OperatorsEnum.Superior)); 71 | break; 72 | case OperatorsEnum.Different: 73 | context.Instructions.Add(new ComparaisonCode(OperatorsEnum.Different)); 74 | break; 75 | case OperatorsEnum.Equals: 76 | context.Instructions.Add(new ComparaisonCode(OperatorsEnum.Equals)); 77 | break; 78 | default: 79 | throw new Exception(); 80 | } 81 | } 82 | public override string ToString() 83 | { 84 | return Operator; 85 | } 86 | 87 | public override void ValidateSemantics(SemanticsValidator validator) 88 | { 89 | 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Nova.Antlr/bin/Debug/NovaLexer.g4: -------------------------------------------------------------------------------- 1 | lexer grammar NovaLexer; 2 | 3 | 4 | USING : 'using'; 5 | 6 | CLASS : 'class'; 7 | STRUCT : 'struct'; 8 | 9 | PUBLIC : 'public'; 10 | PRIVATE : 'private'; 11 | 12 | PRIMITIVE : 'primitive'; 13 | 14 | UNIT: 'unit'; 15 | DOUBLE: 'double'; 16 | FLOAT: 'float'; 17 | INT: 'int'; 18 | SHORT: 'short'; 19 | STRING: 'string'; 20 | BOOLEAN: 'bool'; 21 | CHAR: 'char'; 22 | BYTE: 'byte'; 23 | LONG: 'long'; 24 | 25 | 26 | FOR: 'for'; 27 | IF: 'if'; 28 | WHILE: 'while'; 29 | ELSE: 'else'; 30 | RETURN: 'return'; 31 | 32 | 33 | 34 | NEW: '->'; 35 | 36 | NATIVE: '~'; 37 | 38 | // Operators 39 | 40 | ASSIGN: '='; 41 | ADD: '+'; 42 | SUB: '-'; 43 | MUL: '*'; 44 | DIV: '/'; 45 | LE: '<='; 46 | GE: '>='; 47 | GT: '>'; 48 | LT: '<'; 49 | EQUAL: '=='; 50 | NOTEQUAL: '!='; 51 | AND: '&&'; 52 | OR: '||'; 53 | 54 | // Separators 55 | 56 | LPAREN: '('; 57 | RPAREN: ')'; 58 | LBRACE: '{'; 59 | RBRACE: '}'; 60 | LBRACK: '['; 61 | RBRACK: ']'; 62 | COMMA: ','; 63 | DOT: '.'; 64 | SEMI: ';'; 65 | 66 | // Identifiers 67 | 68 | 69 | NULL_LITERAL: 'null'; 70 | 71 | BOOL_LITERAL: 'true' 72 | | 'false' 73 | ; 74 | IDENTIFIER: Letter LetterOrDigit*; 75 | 76 | 77 | // Fragment Rules 78 | 79 | fragment HexDigits 80 | : HexDigit ((HexDigit | '_')* HexDigit)? 81 | ; 82 | fragment HexDigit 83 | : [0-9a-fA-F] 84 | ; 85 | fragment Digits 86 | : [0-9] ([0-9_]* [0-9])? 87 | ; 88 | fragment LetterOrDigit 89 | : Letter 90 | | [0-9] 91 | ; 92 | fragment Letter 93 | : [a-zA-Z$_] // these are the "java letters" below 0x7F 94 | | ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate 95 | | [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 96 | ; 97 | 98 | fragment EscapeSequence 99 | : '\\' [btnfr"'\\] 100 | | '\\' ([0-3]? [0-7])? [0-7] 101 | | '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit 102 | ; 103 | 104 | WS: [ \t\r\n\u000C]+ -> channel(HIDDEN); 105 | COMMENT: '/*' .*? '*/' -> channel(HIDDEN); 106 | LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN); 107 | 108 | 109 | 110 | // Literals 111 | 112 | DECIMAL_LITERAL: ('0' | [1-9] (Digits? | '_'+ Digits)) [lL]?; 113 | HEX_LITERAL: '0' [xX] [0-9a-fA-F] ([0-9a-fA-F_]* [0-9a-fA-F])? [lL]?; 114 | OCT_LITERAL: '0' '_'* [0-7] ([0-7_]* [0-7])? [lL]?; 115 | BINARY_LITERAL: '0' [bB] [01] ([01_]* [01])? [lL]?; 116 | 117 | FLOAT_LITERAL: (Digits '.' Digits? | '.' Digits) 118 | ; 119 | 120 | HEX_FLOAT_LITERAL: '0' [xX] (HexDigits '.'? | HexDigits? '.' HexDigits) [pP] [+-]? Digits [fFdD]?; 121 | 122 | 123 | 124 | CHAR_LITERAL: '\'' (~['\\\r\n] | EscapeSequence) '\''; 125 | 126 | STRING_LITERAL: '"' (~["\\\r\n] | EscapeSequence)* '"'; 127 | 128 | -------------------------------------------------------------------------------- /Nova.Compiler/Nova.Compiler.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877} 8 | Exe 9 | Nova.Compiler 10 | Nova.Compiler 11 | v4.7.1 12 | 512 13 | true 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | x64 38 | bin\x64\Debug\ 39 | 40 | 41 | x64 42 | bin\x64\Release\ 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | {938E11E6-2ACE-445A-BDF0-14715E209E6D} 66 | Nova.Bytecode 67 | 68 | 69 | {7350E0C1-89BA-49CA-A71F-635916446C35} 70 | Nova.Utils 71 | 72 | 73 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7} 74 | Nova 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # What is Nova 3 | 4 | > Nova is a programming language with a high level of abstraction. This repository contains a bytecode compiler in C# 5 | 6 | 7 | ###### Paradigms: 8 | + Compiled (into bytecode, no JIT for now) 9 | + Structured 10 | + Imperative 11 | + Functional 12 | + Strong typing 13 | ###### Example: 14 | 15 | ``` 16 | using // Nova std library 17 | 18 | // This code is written in Nova ! 19 | class MyClass 20 | { 21 | public int Main() 22 | { 23 | Human human = -> Human("Freddy",18) 24 | human.PrintAge() 25 | 26 | Vector myVect = [7,8,9,10] 27 | myVect.Add(5) 28 | 29 | myVect.Print() // Print '7,8,9,10,5' 30 | } 31 | } 32 | struct Human 33 | { 34 | public string Name 35 | public int Age 36 | 37 | -> Human(string name,int age) // Human constructor 38 | { 39 | Name = name 40 | Age = age 41 | } 42 | 43 | public void PrintAge() 44 | { 45 | Nova.PrintLine(Name + " is " + Age + " years old") 46 | } 47 | } 48 | ``` 49 | ###### How is the language working ? 50 | + Once your nova file(s) source code is written. Just give it to the C# compiler. 51 | + The compiler will generate a .nov file (sources to bytecode) 52 | + Give the .nov to the C++ virtual machine and it will run your program from Main() function. 53 | 54 | ###### Builder 55 | 56 | ![builder](https://puu.sh/F2jxl/e1f80ffc4a.png) 57 | 58 | ###### NOV File 59 | 60 | ![NOV Files](https://puu.sh/F2jDk/390c696ae5.png) 61 | 62 | 63 | ###### How to run 64 | + git clone https://github.com/Skinz3/Nova.git 65 | + Build Nova.Compiler & Nova.VM 66 | + ``` ./Nova.Compiler mySourceFile.nv output.nov ``` ---> myScript.nv must have a main point entry. 67 | + ``` ./Nova.VM output.nov ``` ----> execute the program 68 | 69 | ## Nova Bytecode 70 | 71 | | OpCode | Result | 72 | | :--- | :--- | 73 | | `add` | Add two numbers on top of the stack | 74 | | `comp` | compare two éléments on top of the stack (passing operator as arg)| 75 | | `ctorCall` | Call the constructor of the struct on top of the stack | 76 | | `div` | Divide two numbers on top of the stack | 77 | | `dup` | Duplicate element on top of the stack, and put it on tos| 78 | | `jump` | Define instruction pointer value | 79 | | `jumpIfFalse` | Define instruction pointer if condition is false on tos | 80 | | `load` | Load local value | 81 | | `loadGlobal` | Load static element on top of the stack | 82 | | `call` | Call a method / function | 83 | | `mul` | Multiply two numbers on top of the stack | 84 | | `nat` | Call a native method `(Network, IO, kernel, all system calls in general)` | 85 | | `pushConst` | Push constant value on top of the stack | 86 | | `pushInt` | Push integer on top of the stack (unused) | 87 | | `pushNull` | Push a Null value (nova semantics) on the top of the stack | 88 | | `return` | Set instruction ptr = instructions.length | 89 | | `store` | Store a local value | 90 | | `storeGlobal` | Store a static value | 91 | | `structCallMethod` | Call a struct method | 92 | | `structCreate` | Create a new Struct an put it on tos (typeId as parameter) | 93 | | `structLoadMember` | Load a structure member and put it on tos | 94 | | `structPushCurrent` | Push current executing structure on top of the stack | 95 | | `structStoreMember` | Store tos as a structure member value | 96 | | `sub` | Substract two numbers | 97 | | `vectCreate` | Create a Vector and put it on tos | 98 | 99 | 100 | ## Thanks 101 | 102 | > Thanks to Uriopass (https://github.com/Uriopass) for his precious help 103 | ## Contacts 104 | 105 | > My discord is: **Skinz#1128** 106 | 107 | -------------------------------------------------------------------------------- /Nova/IO/ClassesContainer.cs: -------------------------------------------------------------------------------- 1 | using Nova.Bytecode.IO; 2 | using Nova.Members; 3 | using Nova.Types; 4 | using Nova.Utils; 5 | using System; 6 | using System.Collections; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace Nova.IO 13 | { 14 | public class ClassesContainer : IEnumerable> 15 | { 16 | public int Count 17 | { 18 | get 19 | { 20 | return Elements.Count; 21 | } 22 | } 23 | 24 | private Dictionary Elements 25 | { 26 | get; 27 | set; 28 | } 29 | private Dictionary Relator 30 | { 31 | get; 32 | set; 33 | } 34 | private int RelatorId 35 | { 36 | get; 37 | set; 38 | } 39 | public TypeManager TypeManager 40 | { 41 | get; 42 | set; 43 | } 44 | public ClassesContainer() 45 | { 46 | this.Elements = new Dictionary(); 47 | this.Relator = new Dictionary(); 48 | this.RelatorId = 0; 49 | this.TypeManager = new TypeManager(); 50 | } 51 | public int GetClassId(Class @class) 52 | { 53 | return GetClassId(@class.ClassName); 54 | } 55 | public int GetClassId(string className) 56 | { 57 | return Relator[className]; 58 | } 59 | 60 | public void Add(Class element) 61 | { 62 | Elements.Add(element.ClassName, element); 63 | Relator.Add(element.ClassName, RelatorId++); 64 | } 65 | public void AddRange(Dictionary elements) 66 | { 67 | foreach (var element in elements) 68 | { 69 | Add(element.Value); 70 | } 71 | } 72 | public void AddRange(IEnumerable elements) 73 | { 74 | foreach (var element in elements) 75 | { 76 | Add(element); 77 | } 78 | } 79 | public bool ContainsClass(string @class) 80 | { 81 | return Elements.ContainsKey(@class); 82 | } 83 | public void Concat(ClassesContainer container) 84 | { 85 | AddRange(container.Elements); 86 | } 87 | 88 | public Method ComputeEntryPoint() 89 | { 90 | Method result = null; 91 | 92 | foreach (var @class in GetClasses()) 93 | { 94 | foreach (var method in @class.Methods) 95 | { 96 | if (method.Value.IsMainPointEntry()) 97 | { 98 | if (result != null) 99 | { 100 | return null; 101 | } 102 | 103 | result = method.Value; 104 | } 105 | } 106 | } 107 | 108 | return result; 109 | } 110 | 111 | public IEnumerable GetClasses() 112 | { 113 | return Elements.Values; 114 | } 115 | public Class TryGetClass(string key) 116 | { 117 | Class result = null; 118 | Elements.TryGetValue(key, out result); 119 | return result; 120 | } 121 | public IEnumerator> GetEnumerator() 122 | { 123 | return Elements.GetEnumerator(); 124 | } 125 | 126 | IEnumerator IEnumerable.GetEnumerator() 127 | { 128 | return Elements.GetEnumerator(); 129 | } 130 | 131 | public Class this[string className] 132 | { 133 | get 134 | { 135 | return Elements[className]; 136 | } 137 | } 138 | 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Nova/Members/Class.cs: -------------------------------------------------------------------------------- 1 | using Nova.IO; 2 | using Nova.Lexer; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Text.RegularExpressions; 9 | using System.Threading.Tasks; 10 | using Nova.ByteCode.IO; 11 | using Nova.Semantics; 12 | using Nova.ByteCode.Enums; 13 | using Nova.Bytecode.Enums; 14 | using Nova.Utils; 15 | using Nova.Types; 16 | using Antlr4.Runtime; 17 | 18 | namespace Nova.Members 19 | { 20 | public class Class : IAccessible 21 | { 22 | public string ClassName 23 | { 24 | get; 25 | set; 26 | } 27 | public NvFile File 28 | { 29 | get; 30 | private set; 31 | } 32 | public ContainerType Type 33 | { 34 | get; 35 | private set; 36 | } 37 | public Dictionary Methods 38 | { 39 | get; 40 | private set; 41 | } 42 | public Dictionary Fields 43 | { 44 | get; 45 | private set; 46 | } 47 | private ParserRuleContext Context 48 | { 49 | get; 50 | set; 51 | } 52 | 53 | public Class(NvFile file, string className, ContainerType type, ParserRuleContext context) 54 | { 55 | this.File = file; 56 | this.ClassName = className; 57 | this.Methods = new Dictionary(); 58 | this.Fields = new Dictionary(); 59 | this.Type = type; 60 | this.Context = context; 61 | } 62 | 63 | public Class() 64 | { 65 | this.Methods = new Dictionary(); 66 | this.Fields = new Dictionary(); 67 | } 68 | 69 | 70 | public override string ToString() 71 | { 72 | return ClassName; 73 | } 74 | public Method GetCtor() 75 | { 76 | return Methods.Values.FirstOrDefault(x => x.Type == MethodType.Ctor); 77 | } 78 | public int PopMethodId() 79 | { 80 | return Methods.Count; 81 | } 82 | public int PopFieldId() 83 | { 84 | return Fields.Count; 85 | } 86 | public IByteElement GetByteElement(NovFile file, ClassesContainer container, IByteElement parent) 87 | { 88 | ByteClass byteClass = new ByteClass(file, this.ClassName, Type); 89 | 90 | foreach (var method in this.Methods) 91 | { 92 | byteClass.Methods.Add((ByteMethod)method.Value.GetByteElement(container, byteClass)); 93 | } 94 | 95 | 96 | foreach (var field in this.Fields) 97 | { 98 | byteClass.Fields.Add((ByteField)field.Value.GetByteElement(container, byteClass)); 99 | } 100 | 101 | return byteClass; 102 | 103 | } 104 | 105 | public IEnumerable ValidateSemantics(ClassesContainer container) 106 | { 107 | SemanticsValidator validator = new SemanticsValidator(this, container); 108 | 109 | foreach (var field in this.Fields) 110 | { 111 | field.Value.ValidateSemantics(validator); 112 | validator.Flush(); 113 | } 114 | foreach (var method in this.Methods) 115 | { 116 | method.Value.ValidateSemantics(validator); 117 | validator.Flush(); 118 | } 119 | 120 | return validator.GetErrors(); 121 | } 122 | 123 | public Class GetContextualClass(SemanticsValidator validator) 124 | { 125 | return this; 126 | } 127 | 128 | public IEnumerable ValidateTypes(ClassesContainer container) 129 | { 130 | SemanticsValidator validator = new SemanticsValidator(this, container); 131 | 132 | foreach (var field in this.Fields) 133 | { 134 | field.Value.ValidateTypes(validator); 135 | validator.Flush(); 136 | } 137 | 138 | foreach (var method in this.Methods) 139 | { 140 | method.Value.ValidateTypes(validator); 141 | validator.Flush(); 142 | } 143 | 144 | return validator.GetErrors(); 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /Nova.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29123.88 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nova", "Nova\Nova.csproj", "{8EF17B2E-AF37-444C-B2C0-3B6099321BD7}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nova.Bytecode", "Nova.Bytecode\Nova.Bytecode.csproj", "{938E11E6-2ACE-445A-BDF0-14715E209E6D}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nova.Utils", "Nova.Utils\Nova.Utils.csproj", "{7350E0C1-89BA-49CA-A71F-635916446C35}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nova.Compiler", "Nova.Compiler\Nova.Compiler.csproj", "{02D71F87-48C5-4EE2-83CB-3FFD8B79E877}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nova.Antlr", "Nova.Antlr\Nova.Antlr.csproj", "{0218B638-6FF7-4859-AA0D-0CDF4AB781F8}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Debug|x64 = Debug|x64 20 | Release|Any CPU = Release|Any CPU 21 | Release|x64 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7}.Debug|x64.ActiveCfg = Debug|x64 27 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7}.Debug|x64.Build.0 = Debug|x64 28 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7}.Release|x64.ActiveCfg = Release|x64 31 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7}.Release|x64.Build.0 = Release|x64 32 | {938E11E6-2ACE-445A-BDF0-14715E209E6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {938E11E6-2ACE-445A-BDF0-14715E209E6D}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {938E11E6-2ACE-445A-BDF0-14715E209E6D}.Debug|x64.ActiveCfg = Debug|x64 35 | {938E11E6-2ACE-445A-BDF0-14715E209E6D}.Debug|x64.Build.0 = Debug|x64 36 | {938E11E6-2ACE-445A-BDF0-14715E209E6D}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {938E11E6-2ACE-445A-BDF0-14715E209E6D}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {938E11E6-2ACE-445A-BDF0-14715E209E6D}.Release|x64.ActiveCfg = Release|x64 39 | {938E11E6-2ACE-445A-BDF0-14715E209E6D}.Release|x64.Build.0 = Release|x64 40 | {7350E0C1-89BA-49CA-A71F-635916446C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {7350E0C1-89BA-49CA-A71F-635916446C35}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {7350E0C1-89BA-49CA-A71F-635916446C35}.Debug|x64.ActiveCfg = Debug|x64 43 | {7350E0C1-89BA-49CA-A71F-635916446C35}.Debug|x64.Build.0 = Debug|x64 44 | {7350E0C1-89BA-49CA-A71F-635916446C35}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {7350E0C1-89BA-49CA-A71F-635916446C35}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {7350E0C1-89BA-49CA-A71F-635916446C35}.Release|x64.ActiveCfg = Release|x64 47 | {7350E0C1-89BA-49CA-A71F-635916446C35}.Release|x64.Build.0 = Release|x64 48 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877}.Debug|x64.ActiveCfg = Debug|x64 51 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877}.Debug|x64.Build.0 = Debug|x64 52 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877}.Release|x64.ActiveCfg = Release|x64 55 | {02D71F87-48C5-4EE2-83CB-3FFD8B79E877}.Release|x64.Build.0 = Release|x64 56 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8}.Debug|x64.ActiveCfg = Debug|Any CPU 59 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8}.Debug|x64.Build.0 = Debug|Any CPU 60 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8}.Release|x64.ActiveCfg = Release|Any CPU 63 | {0218B638-6FF7-4859-AA0D-0CDF4AB781F8}.Release|x64.Build.0 = Release|Any CPU 64 | EndGlobalSection 65 | GlobalSection(SolutionProperties) = preSolution 66 | HideSolutionNode = FALSE 67 | EndGlobalSection 68 | GlobalSection(ExtensibilityGlobals) = postSolution 69 | SolutionGuid = {8CC8F65C-D3C2-47D1-BE01-30CE12939570} 70 | EndGlobalSection 71 | EndGlobal 72 | -------------------------------------------------------------------------------- /Nova.Bytecode/Nova.ByteCode.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {938E11E6-2ACE-445A-BDF0-14715E209E6D} 8 | Library 9 | Properties 10 | Nova.Bytecode 11 | Nova.Bytecode 12 | v4.7.1 13 | 512 14 | true 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | x64 36 | bin\x64\Debug\ 37 | 38 | 39 | x64 40 | bin\x64\Release\ 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | {7350E0C1-89BA-49CA-A71F-635916446C35} 100 | Nova.Utils 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Nova/Parser/Listeners/ClassMemberListener.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Misc; 3 | using Antlr4.Runtime.Tree; 4 | using Nova.Bytecode.Enums; 5 | using Nova.ByteCode.Enums; 6 | using Nova.Lexer; 7 | using Nova.Members; 8 | using Nova.Statements; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using static NovaParser; 15 | 16 | namespace Nova.Parser.Listeners 17 | { 18 | public class ClassMemberListener : NovaParserBaseListener 19 | { 20 | private Class Class 21 | { 22 | get; 23 | set; 24 | } 25 | 26 | public ClassMemberListener(Class @class) 27 | { 28 | this.Class = @class; 29 | } 30 | 31 | public override void EnterMemberDeclaration([NotNull] NovaParser.MemberDeclarationContext context) 32 | { 33 | foreach (var memberDeclaration in context.GetRuleContexts()) 34 | { 35 | memberDeclaration.EnterRule(this); 36 | } 37 | } 38 | public override void EnterMethodDeclaration([NotNull] NovaParser.MethodDeclarationContext context) 39 | { 40 | NovaParser.MemberDeclarationContext parent = (NovaParser.MemberDeclarationContext)context.parent; 41 | 42 | string returnType = context.typeTypeOrUnit().GetText(); 43 | string methodName = context.IDENTIFIER().GetText(); 44 | ModifiersEnum modifiers = ParserUtils.ParseModifier(parent.modifier().classModifier().GetText()); 45 | 46 | AddMethod(methodName, returnType, MethodType.Method, modifiers, context, context.formalParameters()); 47 | } 48 | public override void EnterFieldDeclaration([NotNull] NovaParser.FieldDeclarationContext context) 49 | { 50 | NovaParser.MemberDeclarationContext parent = (NovaParser.MemberDeclarationContext)context.parent; 51 | ModifiersEnum modifiers = ParserUtils.ParseModifier(parent.modifier().classModifier().GetText()); 52 | 53 | VariableDeclaratorContext declarator = context.variableDeclarator(); 54 | 55 | string type = context.typeType().GetText(); 56 | string name = declarator.variableDeclaratorId().GetText(); 57 | 58 | Field field = new Field(Class, Class.PopFieldId(), modifiers, new Variable(name, type, context.variableDeclarator())); 59 | 60 | ExpressionNode value = new ExpressionNode(field); 61 | 62 | var initializer = declarator.variableInitializer(); 63 | 64 | if (initializer != null) 65 | { 66 | ExpressionContext expressionContext = initializer.expression(); 67 | 68 | ExpressionListener listener = new ExpressionListener(field); // same here 69 | 70 | foreach (var expression in expressionContext.GetRuleContexts()) 71 | { 72 | expression.EnterRule(listener); 73 | } 74 | 75 | value = listener.GetResult(); 76 | } 77 | 78 | field.Value = value; 79 | 80 | Class.Fields.Add(field.Name, field); 81 | 82 | } 83 | public override void EnterConstructorDeclaration([NotNull] NovaParser.ConstructorDeclarationContext context) 84 | { 85 | NovaParser.MemberDeclarationContext parent = (NovaParser.MemberDeclarationContext)context.parent; 86 | 87 | string returnType = string.Empty; // must be unit 88 | string methodName = context.IDENTIFIER().GetText(); 89 | ModifiersEnum modifiers = ModifiersEnum.@private; // this is not a modifier ! 90 | 91 | AddMethod(methodName, returnType, MethodType.Ctor, modifiers, context, context.formalParameters()); 92 | } 93 | 94 | private void AddMethod(string methodName, string returnType, MethodType type, ModifiersEnum modifiers, ParserRuleContext context, FormalParametersContext parameterContext) 95 | { 96 | List parameters = new List(); 97 | 98 | FormalParameterListContext parameterListContext = parameterContext.formalParameterList(); 99 | 100 | if (parameterListContext != null) 101 | { 102 | foreach (var parameter in parameterListContext.formalParameter()) 103 | { 104 | parameters.Add(new Variable(parameter.variableDeclaratorId().GetText(), parameter.typeType().GetText(), parameter.variableDeclaratorId())); 105 | } 106 | } 107 | 108 | Method method = new Method(Class, Class.PopMethodId(), methodName, modifiers, returnType, 109 | parameters, context); 110 | 111 | method.Type = type; 112 | 113 | StatementListener listener = new StatementListener(method); 114 | 115 | foreach (var methodRule in context.GetRuleContexts()) 116 | { 117 | methodRule.EnterRule(listener); 118 | } 119 | 120 | method.Statements = listener.GetResult(); 121 | 122 | Class.Methods.Add(method.Name, method); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Nova.Antlr/bin/Debug/NovaParser.g4: -------------------------------------------------------------------------------- 1 | 2 | parser grammar NovaParser; 3 | 4 | options { tokenVocab=NovaLexer; } 5 | 6 | compilationUnit 7 | : importDeclaration* typeDeclaration* EOF 8 | ; 9 | 10 | importDeclaration 11 | : USING LT fileName GT 12 | ; 13 | 14 | fileName 15 | : IDENTIFIER '.' IDENTIFIER 16 | ; 17 | 18 | typeDeclaration 19 | : (classDeclaration | structDeclaration | primitiveDeclaration) 20 | ; 21 | 22 | primitiveDeclaration 23 | : PRIMITIVE primitiveTypeOrUnit 24 | classBody 25 | ; 26 | 27 | classDeclaration 28 | : CLASS IDENTIFIER 29 | classBody 30 | ; 31 | 32 | structDeclaration 33 | : STRUCT IDENTIFIER 34 | classBody 35 | ; 36 | 37 | classBody 38 | : '{' (memberDeclaration)* '}' 39 | ; 40 | 41 | memberDeclaration 42 | : modifier methodDeclaration 43 | | modifier fieldDeclaration 44 | | constructorDeclaration 45 | ; 46 | 47 | modifier 48 | : classModifier 49 | ; 50 | 51 | classModifier 52 | : PUBLIC 53 | | PRIVATE 54 | ; 55 | 56 | fieldDeclaration 57 | : typeType variableDeclarator 58 | ; 59 | 60 | variableDeclarator 61 | : variableDeclaratorId (ASSIGN variableInitializer)? 62 | ; 63 | 64 | variableInitializer 65 | : expression 66 | ; 67 | 68 | variableDeclaratorId 69 | : IDENTIFIER 70 | ; 71 | 72 | typeType 73 | : (IDENTIFIER | primitiveType) 74 | ; 75 | 76 | primitiveTypeOrUnit 77 | : (primitiveType | UNIT) 78 | ; 79 | primitiveType 80 | : BOOLEAN 81 | | CHAR 82 | | BYTE 83 | | SHORT 84 | | INT 85 | | STRING 86 | | LONG 87 | | FLOAT 88 | | DOUBLE 89 | ; 90 | 91 | 92 | expression 93 | : methodCall #metCall 94 | | expression bop='.' methodCall #methodAccessor 95 | | expression bop='.' IDENTIFIER #fieldAccessor 96 | | nativeCall #ntvCall 97 | | constructorCall #ctorCall 98 | | primary #primaryValue 99 | | prefix=('+'|'-') expression #unaryExpr 100 | | left=expression bop=('*'|'/') right=expression #binaryExpr 101 | | left=expression bop=('+'|'-') right=expression #binaryExpr 102 | | left=expression ('<' '<' | '>' '>' '>' | '>' '>') right=expression #binaryExpr 103 | | left=expression bop=('<=' | '>=' | '>' | '<') right=expression #binaryExpr 104 | | left=expression bop=('==' | '!=') right=expression #binaryExpr 105 | | left=expression bop='&&' right=expression #binaryExpr 106 | | left=expression bop='||' right=expression #binaryExpr 107 | 108 | ; 109 | 110 | methodDeclaration 111 | : typeTypeOrUnit IDENTIFIER formalParameters 112 | methodBody 113 | ; 114 | 115 | 116 | typeTypeOrUnit 117 | : typeType 118 | | UNIT 119 | ; 120 | 121 | 122 | formalParameters 123 | : '(' formalParameterList? ')' 124 | ; 125 | 126 | formalParameterList 127 | : formalParameter (',' formalParameter)* (',' lastFormalParameter)? 128 | | lastFormalParameter 129 | ; 130 | 131 | formalParameter 132 | : typeType variableDeclaratorId 133 | ; 134 | 135 | lastFormalParameter 136 | : typeType variableDeclaratorId 137 | ; 138 | 139 | constructorDeclaration 140 | : '->' IDENTIFIER formalParameters constructorBody=block 141 | ; 142 | 143 | methodBody 144 | : block 145 | ; 146 | 147 | block 148 | : '{' statement* '}' 149 | ; 150 | 151 | localVariableDeclaration 152 | : typeType variableDeclarator 153 | ; 154 | 155 | statement 156 | : blockLabel=block 157 | | localVariableDeclaration 158 | | ifStatement 159 | | forStatement 160 | | whileStatement 161 | | returnStatement 162 | | assignationStatement 163 | | statementExpression 164 | 165 | ; 166 | whileStatement: 167 | WHILE parExpression statement 168 | ; 169 | returnStatement 170 | : RETURN expression? 171 | ; 172 | 173 | assignationStatement 174 | : left=expression '=' right=expression 175 | ; 176 | 177 | statementExpression 178 | : expression 179 | ; 180 | ifStatement 181 | :IF parExpression ifSt=statement (ELSE elseSt=statement)? 182 | ; 183 | 184 | forStatement 185 | : 186 | FOR '(' forControl ')' statement 187 | ; 188 | 189 | parExpression 190 | : '(' expression ')' 191 | ; 192 | 193 | forControl 194 | : forInit=statement ';' forCond=expression ';' forUpdate=assignationStatement 195 | ; 196 | 197 | 198 | expressionList 199 | : expression (COMMA expression)* 200 | ; 201 | 202 | primary 203 | : '(' expression ')' # primaryExpr 204 | | literal # primarylit 205 | | primaryIdentifier # litIdent 206 | ; 207 | primaryIdentifier 208 | : (IDENTIFIER | primitiveTypeOrUnit) 209 | ; 210 | 211 | literal 212 | : integerLiteral # int 213 | | floatLiteral # float 214 | | CHAR_LITERAL # char 215 | | STRING_LITERAL # string 216 | | BOOL_LITERAL # bool 217 | | NULL_LITERAL # null 218 | ; 219 | 220 | integerLiteral 221 | : DECIMAL_LITERAL 222 | | HEX_LITERAL 223 | | OCT_LITERAL 224 | | BINARY_LITERAL 225 | ; 226 | 227 | floatLiteral 228 | : FLOAT_LITERAL 229 | | HEX_FLOAT_LITERAL 230 | ; 231 | 232 | methodCall 233 | : IDENTIFIER '(' expressionList? ')' 234 | ; 235 | 236 | constructorCall 237 | : NEW creator 238 | ; 239 | 240 | nativeCall 241 | : '~' IDENTIFIER '(' expressionList? ')' 242 | ; 243 | 244 | creator 245 | : createdName (classCreatorRest) 246 | ; 247 | 248 | createdName 249 | : IDENTIFIER 250 | ; 251 | 252 | classCreatorRest 253 | : arguments 254 | ; 255 | 256 | arguments 257 | : '(' expressionList? ')' 258 | ; 259 | 260 | -------------------------------------------------------------------------------- /Nova/Members/Method.cs: -------------------------------------------------------------------------------- 1 | using Nova.ByteCode.Codes; 2 | using Nova.ByteCode.Generation; 3 | using Nova.ByteCode.IO; 4 | using Nova.Lexer; 5 | using Nova.IO; 6 | using Nova.Semantics; 7 | using Nova.Statements; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.IO; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using Nova.ByteCode.Enums; 15 | using Nova.Bytecode.Enums; 16 | using Antlr4.Runtime; 17 | using Nova.Types; 18 | 19 | namespace Nova.Members 20 | { 21 | public class Method : IByteData, IChild, IAccessible 22 | { 23 | public Class ParentClass 24 | { 25 | get; 26 | private set; 27 | } 28 | public string Name 29 | { 30 | get; 31 | set; 32 | } 33 | public int Id 34 | { 35 | get; 36 | set; 37 | } 38 | public ModifiersEnum Modifiers 39 | { 40 | get; 41 | set; 42 | } 43 | public MethodType Type 44 | { 45 | get; 46 | set; 47 | } 48 | public string RawReturnType 49 | { 50 | get; 51 | set; 52 | } 53 | public NovaType ReturnType 54 | { 55 | get; 56 | set; 57 | } 58 | public List Parameters 59 | { 60 | get; 61 | set; 62 | } 63 | public List Statements 64 | { 65 | get; 66 | set; 67 | } 68 | private ParserRuleContext Context 69 | { 70 | get; 71 | set; 72 | } 73 | public IChild Parent => null; 74 | 75 | public Method(Class parentClass, int methodId, string methodName, ModifiersEnum modifiers, string returnType, 76 | List parameters, ParserRuleContext context) 77 | { 78 | this.Id = methodId; 79 | this.ParentClass = parentClass; 80 | this.Name = methodName; 81 | this.Modifiers = modifiers; 82 | this.RawReturnType = returnType; 83 | this.Parameters = parameters; 84 | this.Context = context; 85 | this.Statements = new List(); 86 | } 87 | public bool IsMainPointEntry() 88 | { 89 | return Modifiers == ModifiersEnum.@public && Name == Constants.MainPointEntryMethodName && Parameters.Count == 0; 90 | } 91 | public Method(Class parentClass) 92 | { 93 | this.ParentClass = parentClass; 94 | this.Statements = new List(); 95 | } 96 | 97 | public override string ToString() 98 | { 99 | StringBuilder sb = new StringBuilder(); 100 | 101 | sb.Append(ParentClass + "." + Name); 102 | sb.Append("("); 103 | sb.Append(string.Join(",", Parameters.Select(x => x.ToString()))); 104 | sb.Append(")"); 105 | 106 | return sb.ToString(); 107 | } 108 | 109 | public IByteElement GetByteElement(ClassesContainer container, IByteElement parent) 110 | { 111 | ByteMethod result = new ByteMethod(this.Name, Modifiers, Parameters.Count, (ByteClass)parent); 112 | 113 | foreach (var parameter in Parameters) 114 | { 115 | result.ByteBlock.SymbolTable.Bind(parameter.Name, parameter.RawType); 116 | } 117 | foreach (var statement in Statements) 118 | { 119 | statement.GenerateBytecode(container, result.ByteBlock); 120 | } 121 | 122 | if (result.ByteBlock.Instructions.Count == 0 || (!(result.ByteBlock.Instructions.Last() is ReturnCode))) 123 | { 124 | result.ByteBlock.Instructions.Add(new ReturnCode()); 125 | } 126 | 127 | 128 | return result; 129 | 130 | } 131 | 132 | public void ValidateSemantics(SemanticsValidator validator) 133 | { 134 | if (ParentClass.Type == ContainerType.@struct && IsMainPointEntry()) 135 | { 136 | validator.AddError("Main point entry cannot be member of struct \"" + ParentClass.ClassName + "\"", Context); 137 | } 138 | if (ParentClass.Type == ContainerType.primitive && Parameters.Count == 0) 139 | { 140 | validator.AddError("Primitive method " + Name + " should have self has parameter.", Context); 141 | } 142 | foreach (var param in Parameters) 143 | { 144 | validator.DeclareVariable(param); 145 | } 146 | 147 | foreach (var statement in this.Statements) 148 | { 149 | statement.ValidateSemantics(validator); 150 | } 151 | } 152 | 153 | public void ValidateTypes(SemanticsValidator validator) 154 | { 155 | if (this.Type != MethodType.Ctor) 156 | { 157 | this.ReturnType = validator.Container.TypeManager.GetTypeInstance(RawReturnType); 158 | 159 | if (ReturnType == null) 160 | { 161 | validator.AddError("Unknown return type for method : " + Name, Context); 162 | } 163 | } 164 | 165 | foreach (var parameter in Parameters) 166 | { 167 | parameter.ValidateTypes(validator); 168 | } 169 | 170 | foreach (var statement in Statements) 171 | { 172 | statement.ValidateTypes(validator); 173 | } 174 | } 175 | 176 | public Class GetContextualClass(SemanticsValidator validator) 177 | { 178 | return validator.Container.TryGetClass(RawReturnType); 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /Nova/Expressions/Accessors/Accessor.cs: -------------------------------------------------------------------------------- 1 | using Nova.Bytecode.Codes; 2 | using Nova.Bytecode.Enums; 3 | using Nova.Bytecode.Symbols; 4 | using Nova.ByteCode.Codes; 5 | using Nova.ByteCode.Generation; 6 | using Nova.IO; 7 | using Nova.Members; 8 | using Nova.Semantics; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | 15 | namespace Nova.Expressions.Accessors 16 | { 17 | public class Accessor 18 | { 19 | public SymbolType InferredSymbolType 20 | { 21 | get; 22 | set; 23 | } 24 | public AccessorExpression Expression 25 | { 26 | get; 27 | private set; 28 | } 29 | private IAccessible Target 30 | { 31 | get; 32 | set; 33 | } 34 | public AccessorType Type 35 | { 36 | get 37 | { 38 | return Expression.AccessorType; 39 | } 40 | } 41 | public string Identifier 42 | { 43 | get 44 | { 45 | return Expression.Name; 46 | } 47 | } 48 | public Accessor(AccessorExpression expression) 49 | { 50 | this.Expression = expression; 51 | } 52 | 53 | public T GetTarget() where T : IAccessible 54 | { 55 | return (T)Target; 56 | } 57 | public void SetTarget(IAccessible target) 58 | { 59 | this.Target = target; 60 | } 61 | 62 | public void GenerateStoreBytecode(ClassesContainer container, ByteBlock context) 63 | { 64 | switch (InferredSymbolType) 65 | { 66 | case SymbolType.Local: 67 | Variable variable = GetTarget(); 68 | Symbol symbol = context.SymbolTable.GetSymbol(variable.Name); 69 | context.Instructions.Add(new StoreCode(symbol.Id)); 70 | break; 71 | case SymbolType.ClassMember: 72 | Field target = GetTarget(); 73 | context.Instructions.Add(new StoreGlobalCode(container.GetClassId(target.ParentClass), target.Id)); 74 | break; 75 | case SymbolType.StructMember: 76 | target = GetTarget(); 77 | 78 | if (Expression.ParentClass == target.ParentClass) 79 | { 80 | context.Instructions.Add(new StructPushCurrent()); 81 | } 82 | 83 | context.Instructions.Add(new StructStoreMemberCode(target.Id)); 84 | break; 85 | case SymbolType.ExternalMember: 86 | throw new NotImplementedException(); 87 | default: 88 | break; 89 | } 90 | } 91 | public void GenerateLoadBytecode(ClassesContainer container, ByteBlock context) 92 | { 93 | if (Type == AccessorType.Field) 94 | { 95 | switch (InferredSymbolType) 96 | { 97 | case SymbolType.Local: 98 | Variable variable = GetTarget(); 99 | Symbol symbol = context.SymbolTable.GetSymbol(variable.Name); 100 | context.Instructions.Add(new LoadCode(symbol.Id)); 101 | break; 102 | case SymbolType.ClassMember: 103 | Field target = GetTarget(); 104 | context.Instructions.Add(new LoadGlobalCode(container.GetClassId(target.ParentClass.ClassName), target.Id)); 105 | break; 106 | case SymbolType.StructMember: 107 | target = GetTarget(); 108 | 109 | if (Expression.ParentClass == target.ParentClass) 110 | { 111 | context.Instructions.Add(new StructPushCurrent()); 112 | } 113 | 114 | context.Instructions.Add(new StructLoadMemberCode(target.Id)); 115 | break; 116 | case SymbolType.ExternalMember: 117 | target = GetTarget(); 118 | context.Instructions.Add(new LoadGlobalCode(container.GetClassId(target.ParentClass.ClassName), target.Id)); 119 | break; 120 | default: 121 | break; 122 | } 123 | } 124 | else if (Type == AccessorType.Method) 125 | { 126 | Method target = GetTarget(); 127 | 128 | switch (InferredSymbolType) 129 | { 130 | case SymbolType.ClassMember: 131 | context.Instructions.Add(new MethodCallCode(container.GetClassId(target.ParentClass), target.Id)); 132 | break; 133 | case SymbolType.StructMember: 134 | 135 | if (Expression.ParentClass == target.ParentClass) 136 | { 137 | context.Instructions.Add(new StructPushCurrent()); 138 | } 139 | 140 | context.Instructions.Add(new StructCallMethodCode(target.Id)); 141 | break; 142 | case SymbolType.ExternalMember: 143 | context.Instructions.Add(new MethodCallCode(container.GetClassId(target.ParentClass), target.Id)); 144 | break; 145 | default: 146 | throw new Exception(); 147 | } 148 | } 149 | } 150 | public override string ToString() 151 | { 152 | return Expression.ToString(); 153 | } 154 | 155 | public Class GetTargetClass(SemanticsValidator validator) 156 | { 157 | return Target.GetContextualClass(validator); 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /Nova/IO/NovBuilder.cs: -------------------------------------------------------------------------------- 1 | using Nova.Bytecode.IO; 2 | using Nova.ByteCode.IO; 3 | using Nova.Members; 4 | using Nova.Semantics; 5 | using Nova.Types; 6 | using Nova.Utils; 7 | using Nova.Utils.IO; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.IO; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | 15 | namespace Nova.IO 16 | { 17 | public class NovBuilder 18 | { 19 | public static string STANDARD_LIBRARY_PATH = Path.Combine(Environment.CurrentDirectory, "STD/"); 20 | 21 | public CompilationState State 22 | { 23 | get; 24 | private set; 25 | } 26 | private ClassesContainer Container 27 | { 28 | get; 29 | set; 30 | } 31 | private string OutputPath 32 | { 33 | get; 34 | set; 35 | } 36 | private string InputFilePath 37 | { 38 | get; 39 | set; 40 | } 41 | private NovFile Result 42 | { 43 | get; 44 | set; 45 | } 46 | public NovBuilder(string inputPath, string outputPath) 47 | { 48 | this.InputFilePath = inputPath; 49 | this.OutputPath = outputPath; 50 | } 51 | 52 | public bool Build() 53 | { 54 | State = CompilationState.Parsing; 55 | 56 | NvFile file = OpenNvFile(InputFilePath); 57 | 58 | if (file == null) 59 | { 60 | return false; 61 | } 62 | 63 | if (!CreateContainer(file)) 64 | { 65 | return false; 66 | } 67 | 68 | State = CompilationState.TypeLink; 69 | 70 | List errors = new List(); 71 | 72 | foreach (var @class in Container.GetClasses()) 73 | { 74 | Container.TypeManager.Register(@class, false); 75 | } 76 | 77 | foreach (var @class in Container.GetClasses()) 78 | { 79 | errors.AddRange(@class.ValidateTypes(Container)); 80 | } 81 | 82 | foreach (var @class in Container.GetClasses()) 83 | { 84 | errors.AddRange(@class.ValidateSemantics(Container)); 85 | } 86 | 87 | State = CompilationState.SemanticalValidation; 88 | 89 | if (errors.Count > 0) 90 | { 91 | foreach (var error in errors) 92 | { 93 | Logger.Write(error.ToString(), LogType.SemanticError); 94 | } 95 | return false; 96 | } 97 | 98 | 99 | State = CompilationState.BytecodeGeneration; 100 | 101 | BuildNovFile(); 102 | 103 | State = CompilationState.End; 104 | 105 | if (Result == null) 106 | { 107 | return false; 108 | } 109 | 110 | return true; 111 | } 112 | 113 | /* Tests */ 114 | public void PrintMainByteCode() 115 | { 116 | Result.GetMainMethod().Print(); 117 | } 118 | 119 | 120 | 121 | private static NvFile OpenNvFile(string path) 122 | { 123 | NvFile result = new NvFile(path); 124 | 125 | if (!result.Read()) 126 | { 127 | return null; 128 | } 129 | 130 | return result; 131 | } 132 | private bool CreateContainer(NvFile mainFile) 133 | { 134 | this.Container = new ClassesContainer(); 135 | return CreateContainerRecursively(mainFile, new List()); 136 | 137 | } 138 | private bool CreateContainerRecursively(NvFile file, List usings) 139 | { 140 | foreach (var @class in file.Classes) 141 | { 142 | if (Container.ContainsClass(@class.ClassName)) 143 | { 144 | Logger.Write("Redefinition of class: \"" + @class.ClassName + "\"", LogType.Error); 145 | return false; 146 | } 147 | this.Container.Add(@class); 148 | } 149 | 150 | foreach (var @using in file.Usings) 151 | { 152 | if (!usings.Contains(@using.Value)) 153 | { 154 | string path = string.Empty; 155 | 156 | if (@using.Type == UsingType.Ref) 157 | { 158 | path = Path.Combine(Path.GetDirectoryName(InputFilePath), @using.Value); 159 | } 160 | else 161 | { 162 | throw new Exception(); 163 | } 164 | 165 | NvFile nvFile = OpenNvFile(path); 166 | 167 | if (nvFile == null) 168 | { 169 | return false; 170 | } 171 | 172 | usings.Add(@using.Value); 173 | 174 | return CreateContainerRecursively(nvFile, usings); 175 | } 176 | } 177 | return true; 178 | } 179 | public void Save() 180 | { 181 | if (File.Exists(OutputPath)) 182 | { 183 | File.Delete(OutputPath); 184 | } 185 | 186 | FileStream stream = new FileStream(OutputPath, FileMode.Append); 187 | CppBinaryWriter writer = new CppBinaryWriter(stream); 188 | this.Result.Serialize(writer); 189 | writer.Close(); 190 | stream.Close(); 191 | 192 | } 193 | 194 | private void BuildNovFile() 195 | { 196 | 197 | Method mainEntryPoint = Container.ComputeEntryPoint(); 198 | 199 | if (mainEntryPoint != null) 200 | { 201 | this.Result = new NovFile(); 202 | 203 | this.Result.MainPointEntry = new MainPointEntry(Container.GetClassId(mainEntryPoint.ParentClass), mainEntryPoint.Id); 204 | 205 | foreach (var @class in Container) 206 | { 207 | ByteClass byteClass = (ByteClass)@class.Value.GetByteElement(Result, Container, null); 208 | Result.ByteClasses.Add(byteClass); 209 | } 210 | } 211 | else 212 | { 213 | Logger.Write("Invalid or multiple program entry point.", LogType.Error); 214 | } 215 | 216 | } 217 | 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /Nova/Parser/Listeners/StatementListener.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Misc; 3 | using Antlr4.Runtime.Tree; 4 | using Nova.Expressions; 5 | using Nova.Expressions.Accessors; 6 | using Nova.Lexer; 7 | using Nova.Members; 8 | using Nova.Statements; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using static NovaParser; 15 | 16 | namespace Nova.Parser.Listeners 17 | { 18 | public class StatementListener : NovaParserBaseListener 19 | { 20 | private List Result 21 | { 22 | get; 23 | set; 24 | } 25 | private IChild Parent 26 | { 27 | get; 28 | set; 29 | } 30 | public StatementListener(IChild parent) 31 | { 32 | this.Parent = parent; 33 | this.Result = new List(); 34 | } 35 | /* 36 | * Assignation 37 | * [Type] [Identifier] = [ExpressionNode] 38 | */ 39 | public override void EnterAssignationStatement([NotNull] AssignationStatementContext context) 40 | { 41 | AssignationStatement statement = new AssignationStatement(Parent, context); 42 | 43 | ExpressionListener listener = new ExpressionListener(statement); 44 | context.right.EnterRule(listener); 45 | ExpressionNode value = listener.GetResult(); 46 | statement.Value = value; 47 | 48 | listener = new ExpressionListener(statement); 49 | context.left.EnterRule(listener); 50 | 51 | statement.Target = listener.GetResult().Get(0); 52 | 53 | statement.Operator = '='; 54 | 55 | Result.Add(statement); 56 | } 57 | 58 | public override void EnterWhileStatement([NotNull] WhileStatementContext context) 59 | { 60 | WhileStatement whileStatement = new WhileStatement(Parent, context); 61 | 62 | ExpressionListener expressionListener = new ExpressionListener(whileStatement); 63 | context.parExpression().expression().EnterRule(expressionListener); 64 | whileStatement.Condition = expressionListener.GetResult(); 65 | 66 | StatementListener statementListener = new StatementListener(whileStatement); 67 | context.statement().EnterRule(statementListener); 68 | whileStatement.Statements = statementListener.Result; 69 | 70 | Result.Add(whileStatement); 71 | } 72 | 73 | public override void EnterReturnStatement([NotNull] ReturnStatementContext context) 74 | { 75 | ReturnStatement returnStatement = new ReturnStatement(Parent, context); 76 | 77 | if (context.expression() != null) 78 | { 79 | ExpressionListener listener = new ExpressionListener(returnStatement); 80 | 81 | context.expression().EnterRule(listener); 82 | 83 | returnStatement.Value = listener.GetResult(); 84 | 85 | } 86 | Result.Add(returnStatement); 87 | } 88 | public override void EnterLocalVariableDeclaration([NotNull] NovaParser.LocalVariableDeclarationContext context) 89 | { 90 | VariableDeclaratorContext declarator = context.variableDeclarator(); 91 | 92 | string type = context.typeType().GetChild(0).GetText(); 93 | string name = declarator.variableDeclaratorId().GetText(); 94 | 95 | DeclarationStatement statement = new DeclarationStatement(Parent, context); 96 | 97 | Variable variable = new Variable(name, type,context.variableDeclarator()); 98 | 99 | ExpressionNode value = new ExpressionNode(statement); 100 | 101 | VariableInitializerContext initializer = declarator.variableInitializer(); 102 | 103 | if (initializer != null) 104 | { 105 | ExpressionContext expressionContext = initializer.expression(); 106 | ExpressionListener listener = new ExpressionListener(statement); 107 | 108 | expressionContext.EnterRule(listener); 109 | 110 | value = listener.GetResult(); 111 | 112 | } 113 | 114 | statement.Variable = variable; 115 | statement.Value = value; 116 | 117 | Result.Add(statement); 118 | } 119 | public override void EnterIfStatement([NotNull] IfStatementContext context) 120 | { 121 | IfStatement statement = new IfStatement(Parent, context); 122 | 123 | ExpressionListener listener = new ExpressionListener(statement); 124 | context.parExpression().expression().EnterRule(listener); 125 | statement.IfCondition = listener.GetResult(); 126 | 127 | StatementListener statementListener = new StatementListener(statement); 128 | context.ifSt.EnterRule(statementListener); 129 | statement.IfStatements = statementListener.GetResult(); 130 | 131 | if (context.elseSt != null) 132 | { 133 | statementListener = new StatementListener(statement); 134 | context.elseSt.EnterRule(statementListener); 135 | statement.ElseStatements = statementListener.GetResult(); 136 | } 137 | 138 | Result.Add(statement); 139 | } 140 | public override void EnterForStatement([NotNull] ForStatementContext context) 141 | { 142 | ForStatement statement = new ForStatement(Parent, context); 143 | 144 | StatementListener statementListener = new StatementListener(statement); 145 | context.forControl().forInit.EnterRule(statementListener); 146 | statement.Init = statementListener.GetResult().First(); 147 | 148 | statementListener = new StatementListener(statement); 149 | context.statement().EnterRule(statementListener); 150 | statement.Statements = statementListener.GetResult(); 151 | 152 | ExpressionListener expressionListener = new ExpressionListener(statement); 153 | context.forControl().forCond.EnterRule(expressionListener); 154 | statement.Condition = expressionListener.GetResult(); 155 | 156 | statementListener = new StatementListener(statement); 157 | context.forControl().forUpdate.EnterRule(statementListener); 158 | statement.Update = statementListener.GetResult().First(); 159 | 160 | Result.Add(statement); 161 | 162 | 163 | 164 | } 165 | public override void EnterStatementExpression([NotNull] StatementExpressionContext context) 166 | { 167 | ExpressionStatement statement = new ExpressionStatement(Parent, context); 168 | 169 | ExpressionListener listener = new ExpressionListener(statement); 170 | 171 | context.expression().EnterRule(listener); 172 | 173 | ExpressionNode value = listener.GetResult(); 174 | 175 | statement.Expression = value; 176 | 177 | Result.Add(statement); 178 | } 179 | public override void EnterStatement([NotNull] StatementContext context) 180 | { 181 | foreach (var statement in context.GetRuleContexts()) 182 | { 183 | statement.EnterRule(this); 184 | } 185 | } 186 | public override void EnterBlock([NotNull] BlockContext context) 187 | { 188 | foreach (var rule in context.GetRuleContexts()) 189 | { 190 | rule.EnterRule(this); 191 | } 192 | } 193 | public override void EnterMethodBody([NotNull] MethodBodyContext context) 194 | { 195 | foreach (var blockContext in context.GetRuleContexts()) 196 | { 197 | foreach (var rule in blockContext.GetRuleContexts()) 198 | { 199 | rule.EnterRule(this); 200 | } 201 | } 202 | } 203 | 204 | public List GetResult() 205 | { 206 | return Result; 207 | } 208 | } 209 | 210 | } 211 | -------------------------------------------------------------------------------- /Nova/Nova.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {8EF17B2E-AF37-444C-B2C0-3B6099321BD7} 9 | Library 10 | Properties 11 | Nova 12 | Nova 13 | v4.7.1 14 | 512 15 | true 16 | 17 | 18 | 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | preview 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | preview 38 | 39 | 40 | x64 41 | bin\x64\Debug\ 42 | preview 43 | 44 | 45 | x64 46 | bin\x64\Release\ 47 | preview 48 | 49 | 50 | 51 | ..\packages\Antlr4.Runtime.4.6.6\lib\net45\Antlr4.Runtime.dll 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | {938E11E6-2ACE-445A-BDF0-14715E209E6D} 123 | Nova.Bytecode 124 | 125 | 126 | {7350E0C1-89BA-49CA-A71F-635916446C35} 127 | Nova.Utils 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | Ce projet fait référence à des packages NuGet qui sont manquants sur cet ordinateur. Utilisez l'option de restauration des packages NuGet pour les télécharger. Pour plus d'informations, consultez http://go.microsoft.com/fwlink/?LinkID=322105. Le fichier manquant est : {0}. 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /Nova/Parser/Listeners/ExpressionListener.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Misc; 3 | using Antlr4.Runtime.Tree; 4 | using Nova.ByteCode.Codes; 5 | using Nova.Expressions; 6 | using Nova.Expressions.Accessors; 7 | using Nova.Lexer; 8 | using Nova.Members; 9 | using Nova.Utils; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Linq; 13 | using System.Text; 14 | using System.Threading.Tasks; 15 | using static NovaParser; 16 | 17 | namespace Nova.Parser.Listeners 18 | { 19 | public class ExpressionListener : NovaParserBaseListener 20 | { 21 | private IChild Parent 22 | { 23 | get; 24 | set; 25 | } 26 | private ExpressionNode Result 27 | { 28 | get; 29 | set; 30 | } 31 | 32 | public ExpressionListener(IChild parent) 33 | { 34 | this.Parent = parent; 35 | this.Result = new ExpressionNode(Parent); 36 | } 37 | 38 | public override void EnterPrimary([NotNull] PrimaryContext context) 39 | { 40 | foreach (var rule in context.GetRuleContexts()) 41 | { 42 | rule.EnterRule(this); 43 | } 44 | } 45 | public override void EnterPrimaryExpr([NotNull] PrimaryExprContext context) 46 | { 47 | foreach (var rule in context.GetRuleContexts()) 48 | { 49 | rule.EnterRule(this); 50 | } 51 | } 52 | 53 | public override void EnterPrimarylit([NotNull] PrimarylitContext context) 54 | { 55 | foreach (var rule in context.GetRuleContexts()) 56 | { 57 | rule.EnterRule(this); 58 | } 59 | 60 | } 61 | 62 | 63 | public override void EnterChar([NotNull] CharContext context) 64 | { 65 | base.EnterChar(context); 66 | } 67 | public override void EnterBool([NotNull] BoolContext context) 68 | { 69 | bool value = bool.Parse(context.BOOL_LITERAL().GetText()); 70 | this.Result.Insert(new ConstBoolExpression(Result, context, value)); 71 | } 72 | public override void EnterNull([NotNull] NullContext context) 73 | { 74 | base.EnterNull(context); 75 | } 76 | public override void EnterString([NotNull] StringContext context) 77 | { 78 | string value = context.STRING_LITERAL().GetText().Replace("\"", ""); 79 | this.Result.Insert(new ConstStringExpression(Result, context, value)); 80 | } 81 | public override void EnterInt([NotNull] IntContext context) 82 | { 83 | this.Result.Insert(new ConstIntExpression(Result, context, int.Parse(context.GetText()))); 84 | } 85 | 86 | public override void EnterNativeCall([NotNull] NativeCallContext context) 87 | { 88 | NativeCallExpression expr = new NativeCallExpression(Result, context.IDENTIFIER().GetText(), context); 89 | expr.Parameters = GetMethodCallParameters(expr, context, context.expressionList()); 90 | this.Result.Insert(expr); 91 | } 92 | public override void EnterCtorCall([NotNull] CtorCallContext context) 93 | { 94 | StructCallCtorExpression expr = new StructCallCtorExpression(Result, context.constructorCall().creator().createdName().GetText(), context); 95 | expr.Parameters = GetMethodCallParameters(expr, context, context.constructorCall().creator().classCreatorRest().arguments().expressionList()); 96 | this.Result.Insert(expr); 97 | } 98 | 99 | public override void EnterMethodAccessor([NotNull] MethodAccessorContext context) 100 | { 101 | MethodCallExpression expr = new MethodCallExpression(Result, context); 102 | 103 | expr.Name = context.methodCall().IDENTIFIER().GetText(); 104 | 105 | ExpressionListener expressionListener = new ExpressionListener(expr); 106 | context.expression().EnterRule(expressionListener); 107 | 108 | expr.ParentAccessor = expressionListener.Result.Get(0); 109 | 110 | expr.Parameters = GetMethodCallParameters(expr, context, context.methodCall().expressionList()); 111 | 112 | this.Result.Insert(expr); 113 | } 114 | public override void EnterMethodCall([NotNull] MethodCallContext context) 115 | { 116 | MethodCallExpression expr = new MethodCallExpression(Result, context); 117 | 118 | expr.Name = context.IDENTIFIER().GetText(); 119 | expr.ParentAccessor = null; 120 | expr.Parameters = GetMethodCallParameters(expr, context, context.expressionList()); 121 | this.Result.Insert(expr); 122 | } 123 | public override void EnterFieldAccessor([NotNull] FieldAccessorContext context) 124 | { 125 | VariableNameExpression expr = new VariableNameExpression(Result, context); 126 | 127 | expr.Name = context.IDENTIFIER().GetText(); 128 | 129 | ExpressionListener expressionListener = new ExpressionListener(expr); 130 | context.expression().EnterRule(expressionListener); 131 | expr.ParentAccessor = expressionListener.Result.Get(0); 132 | 133 | this.Result.Insert(expr); 134 | 135 | } 136 | public override void EnterLitIdent([NotNull] LitIdentContext context) 137 | { 138 | VariableNameExpression expression = new VariableNameExpression(Result, context); 139 | expression.Name = context.GetText(); 140 | expression.ParentAccessor = null; 141 | Result.Insert(expression); 142 | } 143 | 144 | private List GetMethodCallParameters(IChild parent, ParserRuleContext context, ExpressionListContext expressionListContext) 145 | { 146 | List results = new List(); 147 | 148 | if (expressionListContext != null) 149 | { 150 | var parameters = expressionListContext.GetRuleContexts(); 151 | 152 | foreach (var parameter in parameters) 153 | { 154 | ExpressionListener listener = new ExpressionListener(parent); 155 | 156 | parameter.EnterRule(listener); 157 | 158 | ExpressionNode result = listener.GetResult(); 159 | results.Add(result); 160 | 161 | } 162 | } 163 | 164 | return results; 165 | } 166 | 167 | public override void EnterUnaryExpr([NotNull] UnaryExprContext context) 168 | { 169 | Logger.Write("Unary operators are not handled properly.", LogType.Warning); 170 | 171 | this.Result.Insert(new OperatorExpression(Result, context.prefix.Text, context)); 172 | context.expression().EnterRule(this); 173 | this.Result.Insert(new ConstIntExpression(Parent, context, 0)); 174 | 175 | } 176 | public override void EnterBinaryExpr([NotNull] BinaryExprContext context) 177 | { 178 | this.Result.Insert(new OperatorExpression(Result, context.bop.Text, context)); 179 | context.right.EnterRule(this); 180 | context.left.EnterRule(this); 181 | } 182 | public override void EnterNtvCall([NotNull] NtvCallContext context) 183 | { 184 | context.nativeCall().EnterRule(this); 185 | } 186 | public override void EnterMetCall([NotNull] MetCallContext context) 187 | { 188 | context.methodCall().EnterRule(this); 189 | } 190 | public override void EnterLiteral([NotNull] LiteralContext context) 191 | { 192 | foreach (var rule in context.GetRuleContexts()) 193 | { 194 | rule.EnterRule(this); // integer litteral , bool litteral etc 195 | } 196 | } 197 | public override void EnterPrimaryValue([NotNull] PrimaryValueContext context) 198 | { 199 | context.primary().EnterRule(this); 200 | } 201 | 202 | public ExpressionNode GetResult() 203 | { 204 | return this.Result; 205 | } 206 | } 207 | } 208 | --------------------------------------------------------------------------------