├── .gitignore ├── Assets └── doge.ico ├── DogeSharp.sln ├── DogeSharp ├── CompilerException.cs ├── DogeSharp.csproj ├── DogeSharp.g4 ├── DogeToCSTranslator.cs ├── Program.cs ├── build_grammar.sh └── packages.config ├── Samples ├── .gitignore ├── Libs │ ├── .gitignore │ ├── Servya.Http.dll │ └── Servya.dll ├── Main.ds ├── MyType.ds ├── Samples.csproj ├── Server.ds ├── WinForms.ds ├── build.bat └── build.sh ├── licence └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pgc 27 | *.pgd 28 | *.rsp 29 | *.sbr 30 | *.tlb 31 | *.tli 32 | *.tlh 33 | *.tmp 34 | *.log 35 | *.vspscc 36 | *.vssscc 37 | .builds 38 | 39 | # Visual C++ cache files 40 | ipch/ 41 | *.aps 42 | *.ncb 43 | *.opensdf 44 | *.sdf 45 | 46 | # Visual Studio profiler 47 | *.psess 48 | *.vsp 49 | *.vspx 50 | 51 | # Guidance Automation Toolkit 52 | *.gpState 53 | 54 | # ReSharper is a .NET coding add-in 55 | _ReSharper* 56 | 57 | # NCrunch 58 | *.ncrunch* 59 | .*crunch*.local.xml 60 | 61 | # Installshield output folder 62 | [Ee]xpress 63 | 64 | # DocProject is a documentation generator add-in 65 | DocProject/buildhelp/ 66 | DocProject/Help/*.HxT 67 | DocProject/Help/*.HxC 68 | DocProject/Help/*.hhc 69 | DocProject/Help/*.hhk 70 | DocProject/Help/*.hhp 71 | DocProject/Help/Html2 72 | DocProject/Help/html 73 | 74 | # Click-Once directory 75 | publish 76 | 77 | # Publish Web Output 78 | *.Publish.xml 79 | 80 | # NuGet Packages Directory 81 | packages 82 | 83 | # Windows Azure Build Output 84 | csx 85 | *.build.csdef 86 | 87 | # Windows Store app package directory 88 | AppPackages/ 89 | 90 | # Others 91 | [Bb]in 92 | [Oo]bj 93 | sql 94 | TestResults 95 | [Tt]est[Rr]esult* 96 | *.Cache 97 | ClientBin 98 | [Ss]tyle[Cc]op.* 99 | ~$* 100 | *.dbmdl 101 | Generated_Code #added for RIA/Silverlight projects 102 | 103 | # Backup & report files from converting an old project file to a newer 104 | # Visual Studio version. Backup files are not needed, because we have git ;-) 105 | _UpgradeReport_Files/ 106 | Backup*/ 107 | UpgradeLog*.XML 108 | 109 | *.userprefs -------------------------------------------------------------------------------- /Assets/doge.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/returnString/DogeSharp/cbb9af3aed3cdff040a1dbf8c5182dded754fa3b/Assets/doge.ico -------------------------------------------------------------------------------- /DogeSharp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30501.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DogeSharp", "DogeSharp\DogeSharp.csproj", "{CFB5A41C-EDDD-475A-86E7-F426CC705B56}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples.csproj", "{8CD963C3-9DCD-4854-A3EA-970B94F2E488}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {CFB5A41C-EDDD-475A-86E7-F426CC705B56} = {CFB5A41C-EDDD-475A-86E7-F426CC705B56} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Any CPU = Debug|Any CPU 16 | Release|Any CPU = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {CFB5A41C-EDDD-475A-86E7-F426CC705B56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {CFB5A41C-EDDD-475A-86E7-F426CC705B56}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {CFB5A41C-EDDD-475A-86E7-F426CC705B56}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {CFB5A41C-EDDD-475A-86E7-F426CC705B56}.Release|Any CPU.Build.0 = Release|Any CPU 23 | {8CD963C3-9DCD-4854-A3EA-970B94F2E488}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {8CD963C3-9DCD-4854-A3EA-970B94F2E488}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {8CD963C3-9DCD-4854-A3EA-970B94F2E488}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {8CD963C3-9DCD-4854-A3EA-970B94F2E488}.Release|Any CPU.Build.0 = Release|Any CPU 27 | EndGlobalSection 28 | GlobalSection(SolutionProperties) = preSolution 29 | HideSolutionNode = FALSE 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /DogeSharp/CompilerException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Antlr4.Runtime; 3 | 4 | namespace DogeSharp 5 | { 6 | public class CompilerException : Exception 7 | { 8 | public CompilerException(string message, params object[] args) 9 | : base(string.Format(message, args)) 10 | { 11 | } 12 | 13 | public CompilerException(IToken token, string message, params object[] args) 14 | : this(message + LineInfo(token), args) 15 | { 16 | } 17 | 18 | private static string LineInfo(IToken token) 19 | { 20 | return string.Format(" (token '{0}', line {1}, column {2})", token.Text, token.Line, token.Column); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /DogeSharp/DogeSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {CFB5A41C-EDDD-475A-86E7-F426CC705B56} 9 | Exe 10 | Properties 11 | DogeSharp 12 | dsc 13 | v4.5 14 | 512 15 | fb37d05d 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | true 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | true 35 | 36 | 37 | ..\Assets\doge.ico 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | ..\packages\Antlr4.Runtime.4.3.0\lib\net45\Antlr4.Runtime.net45.dll 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Generated\DogeSharpBaseListener.cs 57 | 58 | 59 | Generated\DogeSharpBaseVisitor.cs 60 | 61 | 62 | Generated\DogeSharpLexer.cs 63 | 64 | 65 | Generated\DogeSharpListener.cs 66 | 67 | 68 | Generated\DogeSharpParser.cs 69 | 70 | 71 | Generated\DogeSharpVisitor.cs 72 | 73 | 74 | 75 | 76 | MSBuild:Compile 77 | DogeSharp 78 | 79 | 80 | 81 | 82 | 83 | 84 | $(ProjectDir)..\packages\Antlr4.4.3.0\build 85 | 86 | $(ProjectDir)..\packages\Antlr4.4.3.0\tools\antlr4-csharp-4.3-complete.jar 87 | 88 | 89 | 90 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 91 | 92 | 93 | 94 | 95 | 96 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /DogeSharp/DogeSharp.g4: -------------------------------------------------------------------------------- 1 | grammar DogeSharp; 2 | 3 | prog: 4 | useNamespace* declareClass*; 5 | 6 | stmt: 7 | expr+ ';'; 8 | 9 | expr: 10 | 'such' ID=Ident Expr=expr # Declare 11 | | Left=expr 'so' Right=expr # Assign 12 | | Pre=('plz'|'gimme') (Expr=expr '.')? ID=Ident ('many' expr+)? # Call 13 | | Target=expr '.' ID=Ident # GetField 14 | | 'wow' Expr=expr # Print 15 | | Value=Ident # Ident 16 | | Value=Number # Number 17 | | '"' (~'"')* '"' # String 18 | | 'so op' Left=expr (Operator expr)+ # Operation 19 | | 'amaze' Expr=expr? # Return 20 | | Left=expr 'much handled' Right=expr # HandleEvent 21 | | 'to the moon' Expr=expr # Await 22 | ; 23 | 24 | conditionalElse: 25 | Pre=('but'|'but rly') expr? '{' scopeBlock '}'; 26 | 27 | conditional: 28 | 'rly' expr '{' scopeBlock '}' conditionalElse*; 29 | 30 | scopeBlock: 31 | (stmt|block|conditional)*; 32 | 33 | block: 34 | 'very resource' Expr=expr '{' scopeBlock '}' # Using 35 | | 'many lock' ID=Ident '{' scopeBlock '}' # Lock 36 | ; 37 | 38 | declareFunction: 39 | attribute* 'very' ID=Ident ('so' ReturnType=Ident)? ('many' (Ident Ident)*)? ('much' Modifier)* scopeBlock; 40 | 41 | classProperty: 42 | attribute* 'such' Name=Ident 'so' Type=Ident ('much' Modifier)*; 43 | 44 | declareClass: 45 | attribute* 'much' ID=Ident ('so' Ident)* Hidden='much hidden'? (classProperty|declareFunction)*; 46 | 47 | useNamespace: 48 | 'many' ID=Ident; 49 | 50 | attribute: 51 | '[' 'such' ID=Ident ('many' expr+)? ']'; 52 | 53 | Modifier: 54 | 'static'|'public'|'readonly'|'protected'|'override'|'virtual'|'async'|'private'; 55 | Operator: 56 | '+'|'-'|'*'|'/'|'=='|'!='|'>'|'>='|'<'|'<='; 57 | Number: 58 | [0-9]+; 59 | Ident: 60 | IdentPart ('.' IdentPart)*; 61 | IdentPart: 62 | IdentChar(IdentChar|Number)*; 63 | IdentChar: 64 | [a-zA-Z]|'<'|'>'; 65 | WS: 66 | (' '|'\r'|'\n'|'\t') -> channel(HIDDEN); -------------------------------------------------------------------------------- /DogeSharp/DogeToCSTranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Antlr4.Runtime; 5 | 6 | namespace DogeSharp 7 | { 8 | public class DogeToCSTranslator : DogeSharpBaseVisitor 9 | { 10 | const string QuoteStr = "\""; 11 | 12 | private readonly string m_filename; 13 | 14 | public DogeToCSTranslator(string filename) 15 | { 16 | m_filename = filename; 17 | } 18 | 19 | public override string VisitCall(DogeSharpParser.CallContext context) 20 | { 21 | var name = context.ID.Text; 22 | var expr = context.expr(); 23 | 24 | // Skip the left side for the arg list 25 | if (context.Expr != null) 26 | expr = expr.Skip(1).ToList(); 27 | 28 | var args = expr.Select(e => Visit(e)); 29 | 30 | var call = string.Format("{0}({1})", name, string.Join(",", args)); 31 | var prefix = context.Expr != null ? Visit(context.Expr) + "." : ""; 32 | 33 | switch (context.Pre.Text) 34 | { 35 | // Call 36 | case "plz": 37 | return prefix + call; 38 | 39 | // Ctor 40 | case "gimme": 41 | return string.Format("new {0}{1}", prefix, call); 42 | 43 | default: 44 | throw new CompilerException(context.Pre, "very unexpect, much token"); 45 | } 46 | } 47 | 48 | public override string VisitDeclare(DogeSharpParser.DeclareContext context) 49 | { 50 | return string.Format("var {0} = {1}", context.ID.Text, Visit(context.Expr)); 51 | } 52 | 53 | public override string VisitNumber(DogeSharpParser.NumberContext context) 54 | { 55 | return context.Value.Text; 56 | } 57 | 58 | public override string VisitString(DogeSharpParser.StringContext context) 59 | { 60 | // It works, and that's what important... right? Need to learn ANTLR properly. 61 | return QuoteStr + string.Join(" ", context.children.Select(c => c.GetText()).Skip(1).TakeWhile(s => s != QuoteStr)) + QuoteStr; 62 | } 63 | 64 | public override string VisitIdent(DogeSharpParser.IdentContext context) 65 | { 66 | return context.Value.Text; 67 | } 68 | 69 | public override string VisitPrint(DogeSharpParser.PrintContext context) 70 | { 71 | // Need a full reference in case System isn't in scope 72 | return "System.Console.WriteLine(" + Visit(context.Expr) + ")"; 73 | } 74 | 75 | // TODO: Automatic ctor generation, structs 76 | public override string VisitDeclareClass(DogeSharpParser.DeclareClassContext context) 77 | { 78 | var props = context.classProperty().Select(p => Visit(p)); 79 | var methods = context.declareFunction().Select(m => Visit(m)); 80 | var inherits = context.Ident().Skip(1).Select(i => i.ToString()); 81 | var inheritStr = string.Join(", ", inherits); 82 | if (!string.IsNullOrEmpty(inheritStr)) 83 | inheritStr = ": " + inheritStr; 84 | 85 | var attributes = string.Join(" ", context.attribute().Select(a => Visit(a))); 86 | var modifier = context.Hidden != null ? "internal" : "public"; 87 | 88 | return string.Format("{0} {1} class {2} {3} {{ {4} {5} }}", attributes, modifier, context.ID.Text, inheritStr, 89 | string.Join(Environment.NewLine, props), string.Join(Environment.NewLine, methods)); 90 | } 91 | 92 | public override string VisitDeclareFunction(DogeSharpParser.DeclareFunctionContext context) 93 | { 94 | var skip = 1; 95 | var name = context.ID.Text; 96 | 97 | var attributes = string.Join(" ", context.attribute().Select(a => Visit(a))); 98 | 99 | var returnType = ""; 100 | if (context.ReturnType != null) 101 | { 102 | returnType = context.ReturnType.Text; 103 | skip += 1; 104 | } 105 | 106 | var modifiers = string.Join(" ", context.Modifier().Select(m => m.Symbol.Text)); 107 | 108 | var prmString = ""; 109 | var idents = context.Ident(); 110 | 111 | for (var i = skip; i < idents.Count; i += 2) 112 | { 113 | if (i != skip) 114 | prmString += ","; 115 | 116 | prmString += string.Format("{0} {1} ", idents[i], idents[i + 1]); 117 | } 118 | 119 | var block = Visit(context.scopeBlock()); 120 | 121 | return string.Format("{0} {1} {2} {3}({4}) {5}", 122 | attributes, modifiers, returnType, name, prmString, block); 123 | } 124 | 125 | public override string VisitGetField(DogeSharpParser.GetFieldContext context) 126 | { 127 | return context.ID.Text; 128 | } 129 | 130 | public override string VisitOperation(DogeSharpParser.OperationContext context) 131 | { 132 | var ret = Visit(context.Left); 133 | var operators = context.Operator(); 134 | 135 | for (var i = 0; i < operators.Count; i++) 136 | { 137 | var op = operators[i]; 138 | var expr = context.expr(i + 1); 139 | 140 | ret += op.GetText() + Visit(expr); 141 | } 142 | 143 | return ret; 144 | } 145 | 146 | public override string VisitUseNamespace(DogeSharpParser.UseNamespaceContext context) 147 | { 148 | return "using " + context.ID.Text + ";"; 149 | } 150 | 151 | public override string VisitClassProperty(DogeSharpParser.ClassPropertyContext context) 152 | { 153 | var access = "private"; 154 | var getAccess = ""; 155 | var setAccess = ""; 156 | 157 | foreach (var modifier in context.Modifier()) 158 | { 159 | switch (modifier.GetText()) 160 | { 161 | case "static": 162 | access += " static"; 163 | break; 164 | 165 | case "readonly": 166 | access = "public"; 167 | setAccess = "private"; 168 | break; 169 | } 170 | } 171 | 172 | var attributes = string.Join(" ", context.attribute().Select(a => Visit(a))); 173 | 174 | return string.Format("{0} {1} {2} {3} {{ {4} get; {5} set; }}", 175 | attributes, access, context.Type.Text, context.Name.Text, getAccess, setAccess); 176 | } 177 | 178 | public override string VisitReturn(DogeSharpParser.ReturnContext context) 179 | { 180 | if (context.Expr == null) 181 | return "return"; 182 | 183 | return "return " + Visit(context.Expr); 184 | } 185 | 186 | public override string VisitProg(DogeSharpParser.ProgContext context) 187 | { 188 | var namespaces = context.useNamespace().Select(n => Visit(n)); 189 | var classes = context.declareClass().Select(c => Visit(c)); 190 | 191 | return string.Join("", namespaces) + string.Join("", classes); 192 | } 193 | 194 | public override string VisitAssign(DogeSharpParser.AssignContext context) 195 | { 196 | return Visit(context.Left) + '=' + Visit(context.Right); 197 | } 198 | 199 | public override string VisitHandleEvent(DogeSharpParser.HandleEventContext context) 200 | { 201 | return Visit(context.Left) + "+=" + Visit(context.Right); 202 | } 203 | 204 | public override string VisitAttribute(DogeSharpParser.AttributeContext context) 205 | { 206 | return string.Format("[{0}({1})]", context.ID.Text, string.Join(",", context.expr().Select(e => Visit(e)))); 207 | } 208 | 209 | public override string VisitAwait(DogeSharpParser.AwaitContext context) 210 | { 211 | return "await " + Visit(context.Expr); 212 | } 213 | 214 | public override string VisitUsing(DogeSharpParser.UsingContext context) 215 | { 216 | return string.Format("using ({0}) {1}", Visit(context.Expr), Visit(context.scopeBlock())); 217 | } 218 | 219 | public override string VisitScopeBlock(DogeSharpParser.ScopeBlockContext context) 220 | { 221 | return string.Format("{{ {0} }}", CreateBlock(context.stmt(), context.block(), context.conditional())); 222 | } 223 | 224 | public override string VisitStmt(DogeSharpParser.StmtContext context) 225 | { 226 | var exprs = context.expr().Select(c => new { Line = c.Start.Line, Text = Visit(c) }).Where(e => !string.IsNullOrWhiteSpace(e.Text)).ToArray(); 227 | var statements = exprs.Select(e => string.Format("{0}#line {1} \"{2}\" {0} {3};", Environment.NewLine, e.Line, m_filename, e.Text)); 228 | return string.Join(" ", statements); 229 | } 230 | 231 | public override string VisitLock(DogeSharpParser.LockContext context) 232 | { 233 | var block = Visit(context.scopeBlock()); 234 | return string.Format("lock ({0}) {{ {1} }}", context.ID.Text, block); 235 | } 236 | 237 | public override string VisitConditional(DogeSharpParser.ConditionalContext context) 238 | { 239 | var extras = string.Join(" ", context.conditionalElse().Select(c => Visit(c))); 240 | return string.Format("if ({0}) {1} {2}", Visit(context.expr()), Visit(context.scopeBlock()), extras); 241 | } 242 | 243 | public override string VisitConditionalElse(DogeSharpParser.ConditionalElseContext context) 244 | { 245 | var start = "else"; 246 | if (context.Pre.Text == "but rly") 247 | { 248 | start += string.Format(" if ({0})", Visit(context.expr())); 249 | } 250 | 251 | return string.Format("{0} {1}", start, Visit(context.scopeBlock())); 252 | } 253 | 254 | private string CreateBlock(params IEnumerable[] contexts) 255 | { 256 | var block = string.Empty; 257 | 258 | foreach (var entry in Group(contexts)) 259 | { 260 | block += Visit(entry); 261 | } 262 | 263 | return block; 264 | } 265 | 266 | private IEnumerable Group(params IEnumerable[] contexts) 267 | { 268 | return contexts.SelectMany(c => c).OrderBy(c => c.Start.Line); 269 | } 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /DogeSharp/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.CodeDom.Compiler; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | using Antlr4.Runtime; 9 | using Microsoft.CSharp; 10 | 11 | // ANTLR marks its own stuff as CLS compliant, gotta avoid warnings 12 | [assembly: CLSCompliant(false)] 13 | 14 | namespace DogeSharp 15 | { 16 | public static class Program 17 | { 18 | private delegate string Helper(params string[] strings); 19 | 20 | const string AsciiArt = 21 | @" 22 | ▄ ▄ 23 | ▌▒█ ▄▀▒▌ 24 | ▌▒▒█ ▄▀▒▒▒▐ 25 | ▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐ 26 | ▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐ 27 | ▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌ 28 | ▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒▌ 29 | ▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐ 30 | ▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄▌ 31 | ▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▌ 32 | ▀▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒▐ 33 | ▐▒▒▐▀▐▀▒░▄▄▒▄▒▒▒▒▒▒░▒░▒░▒▒▒▒▌ 34 | ▐▒▒▒▀▀▄▄▒▒▒▄▒▒▒▒▒▒▒▒░▒░▒░▒▒▐ 35 | ▌▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒░▒░▒░▒░▒▒▒▌ 36 | ▐▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▒▄▒▒▐ 37 | ▀▄▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▄▒▒▒▒▌ 38 | ▀▄▒▒▒▒▒▒▒▒▒▒▄▄▄▀▒▒▒▒▄▀ 39 | ▀▄▄▄▄▄▄▀▀▀▒▒▒▒▒▄▄▀ 40 | ▒▒▒▒▒▒▒▒▒▒▀▀ 41 | 42 | "; 43 | 44 | public static void Main(string[] args) 45 | { 46 | try 47 | { 48 | MainAsync(args).Wait(); 49 | } 50 | catch (AggregateException ex) 51 | { 52 | Log("much internal error: {0}", ex.InnerException); 53 | } 54 | 55 | if (Debugger.IsAttached) 56 | Console.ReadLine(); 57 | } 58 | 59 | public static async Task MainAsync(string[] args) 60 | { 61 | Console.WriteLine(AsciiArt); 62 | 63 | try 64 | { 65 | m_bufferWidth = Console.BufferWidth / 2; 66 | } 67 | catch (IOException) 68 | { 69 | m_bufferWidth = 40; 70 | } 71 | 72 | Log("many D#"); 73 | Log("very © Ruan Pearce-Authers"); 74 | Log("much programming"); 75 | Log("such language"); 76 | 77 | var parsedArgs = args.Select(a => a.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries)); 78 | var files = parsedArgs.Where(t => t.Length != 2 && !t[0].StartsWith("/")).Select(f => f[0]).ToArray(); 79 | 80 | if (files.Length == 0) 81 | { 82 | Log("very files, much unspecified"); 83 | return; 84 | } 85 | 86 | Helper getArg = names => 87 | { 88 | foreach (var option in parsedArgs) 89 | { 90 | foreach (var name in names) 91 | { 92 | if (option[0].ToLower() == name) 93 | return option.Length > 1 ? option[1] : string.Empty; 94 | } 95 | } 96 | return null; 97 | }; 98 | 99 | var targetType = GetTarget(getArg("/target")); 100 | var targetName = getArg("/out") ?? Path.GetFileNameWithoutExtension(files[0]) + "." + targetType; 101 | 102 | var timer = Stopwatch.StartNew(); 103 | var tasks = new List>(); 104 | 105 | Log("very translating..."); 106 | 107 | var preserveTranslated = getArg("/preservetranslated") != null; 108 | var debug = getArg("/debug") != null; 109 | 110 | foreach (var filename in files) 111 | { 112 | // Silly closure semantics 113 | var actual = filename; 114 | 115 | tasks.Add(Task.Run(async () => 116 | { 117 | using (var file = File.OpenRead(actual)) 118 | { 119 | var input = new AntlrInputStream(file); 120 | var lexer = new DogeSharpLexer(input); 121 | var tokens = new CommonTokenStream(lexer); 122 | var parser = new DogeSharpParser(tokens); 123 | 124 | Log("much translation: {0}", actual); 125 | 126 | parser.RemoveErrorListeners(); 127 | parser.AddErrorListener(new ErrorListener()); 128 | var visitor = new DogeToCSTranslator(actual); 129 | var text = visitor.Visit(parser.prog()); 130 | 131 | if (preserveTranslated) 132 | { 133 | using (var translated = File.Open(actual.Replace(".ds", ".cs"), FileMode.Create)) 134 | using (var stream = new StreamWriter(translated)) 135 | await stream.WriteAsync(text); 136 | } 137 | 138 | return text; 139 | } 140 | })); 141 | } 142 | 143 | var sources = await Task.WhenAll(tasks); 144 | 145 | Helper forwardArgs = names => 146 | { 147 | var temp = new List(); 148 | foreach (var name in names) 149 | { 150 | var value = getArg(name); 151 | if (value != null) 152 | { 153 | var full = name; 154 | if (!string.IsNullOrEmpty(value)) 155 | full += ":" + value; 156 | 157 | temp.Add(full); 158 | } 159 | } 160 | return string.Join(" ", temp); 161 | }; 162 | 163 | var forwardedOptions = forwardArgs("/optimize", "/target"); 164 | 165 | if (!string.IsNullOrEmpty(forwardedOptions)) 166 | Log("so forwarding: {0}", forwardedOptions); 167 | 168 | var assemblies = parsedArgs.Where(t => t[0] == "/reference").Select(t => t[1]).ToArray(); 169 | 170 | Log("very references: {0}", string.Join(", ", assemblies)); 171 | 172 | var provider = new CSharpCodeProvider(); 173 | var options = new CompilerParameters(assemblies, targetName, debug) 174 | { 175 | GenerateExecutable = targetType == "exe" || targetType == "winexe", 176 | CompilerOptions = forwardedOptions 177 | }; 178 | 179 | Log("such translated, wow"); 180 | Log("many compiling..."); 181 | 182 | var results = provider.CompileAssemblyFromSource(options, sources.ToArray()); 183 | 184 | Log("such compiled, wow"); 185 | Log("many time, such elapsed, so milliseconds: {0}", timer.ElapsedMilliseconds); 186 | 187 | if (results.Errors.HasErrors) 188 | { 189 | Log("so errors:"); 190 | foreach (var error in results.Errors) 191 | { 192 | Log(error.ToString()); 193 | } 194 | } 195 | else 196 | { 197 | Log("many success: {0}", results.PathToAssembly); 198 | } 199 | } 200 | 201 | private static Random m_random = new Random(); 202 | private static int m_bufferWidth; 203 | 204 | private static void Log(string message, params object[] args) 205 | { 206 | var indent = new string(' ', m_random.Next(m_bufferWidth)); 207 | var msg = indent + message; 208 | 209 | if (args.Length == 0) 210 | Console.WriteLine(msg); 211 | else 212 | Console.WriteLine(msg, args); 213 | 214 | Console.WriteLine(); 215 | } 216 | 217 | private static string GetTarget(string option) 218 | { 219 | switch (option) 220 | { 221 | case "library": 222 | return "dll"; 223 | 224 | case "winexe": 225 | case "exe": 226 | case null: 227 | return "exe"; 228 | 229 | default: 230 | throw new CompilerException("many target, much invalid"); 231 | } 232 | } 233 | } 234 | 235 | internal class ErrorListener : IAntlrErrorListener 236 | { 237 | public void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) 238 | { 239 | throw new CompilerException(offendingSymbol, "wow, many syntax error: {0}", msg); 240 | } 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /DogeSharp/build_grammar.sh: -------------------------------------------------------------------------------- 1 | java -cp ../packages/Antlr4.4.3.0/tools/antlr4-csharp-4.3-complete.jar org.antlr.v4.CSharpTool -o obj/Debug -listener -visitor -Dlanguage=CSharp_v4_5 -package DogeSharp DogeSharp.g4 2 | -------------------------------------------------------------------------------- /DogeSharp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Samples/.gitignore: -------------------------------------------------------------------------------- 1 | *.cs 2 | *.exe 3 | *.dll -------------------------------------------------------------------------------- /Samples/Libs/.gitignore: -------------------------------------------------------------------------------- 1 | !*.dll -------------------------------------------------------------------------------- /Samples/Libs/Servya.Http.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/returnString/DogeSharp/cbb9af3aed3cdff040a1dbf8c5182dded754fa3b/Samples/Libs/Servya.Http.dll -------------------------------------------------------------------------------- /Samples/Libs/Servya.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/returnString/DogeSharp/cbb9af3aed3cdff040a1dbf8c5182dded754fa3b/Samples/Libs/Servya.dll -------------------------------------------------------------------------------- /Samples/Main.ds: -------------------------------------------------------------------------------- 1 | many System 2 | many System.IO 3 | many System.Threading.Tasks 4 | 5 | much Program much hidden 6 | very Basic so void much static 7 | such x 1; 8 | x so 2; 9 | such y "test"; 10 | wow x; 11 | wow y; 12 | 13 | very FunctionCalls so void much static 14 | such x plz Math.Pow many 2 2; 15 | wow x; 16 | wow plz x.GetType; 17 | such y plz Convert.ToInt32 many x; 18 | wow so op y + 1; 19 | 20 | very Constructors so void much static 21 | such rand gimme Random; 22 | such z so op plz rand.Next + plz rand.Next + 1; 23 | wow z; 24 | 25 | such instance gimme MyType many 1 2; 26 | such result plz instance.Method; 27 | wow instance.data; 28 | wow result; 29 | 30 | very Overflow so void much static 31 | such max int.MaxValue; 32 | such overflow so op max + 1; 33 | wow overflow; 34 | 35 | very Input so void much static 36 | such input plz Console.ReadLine; 37 | wow input; 38 | plz Console.ReadLine; 39 | 40 | very AsyncFunction so Task much static much async 41 | to the moon plz Task.Delay many 1000; 42 | wow "many delay"; 43 | 44 | very WithResource so void much static 45 | very resource such writer gimme StringWriter 46 | { 47 | plz writer.Write many "wow"; 48 | wow plz writer.ToString; 49 | } 50 | 51 | such lockObject so object much readonly much static 52 | 53 | very WithLock so void much static 54 | many lock lockObject 55 | { 56 | such x 1; 57 | } 58 | 59 | very Conditional so void much static 60 | such x 0; 61 | 62 | such rand gimme Random; 63 | such variable plz rand.Next; 64 | 65 | rly so op variable <= 10 66 | { 67 | x so 1; 68 | } 69 | but rly so op variable <= 1000 70 | { 71 | x so 2; 72 | } 73 | but 74 | { 75 | x so 3; 76 | } 77 | 78 | very Main so void much static 79 | lockObject so gimme object; 80 | plz Basic; 81 | plz FunctionCalls; 82 | plz Constructors; 83 | plz Overflow; 84 | plz Input; 85 | plz WithResource; 86 | plz Conditional; 87 | such task plz AsyncFunction; 88 | plz task.Wait; -------------------------------------------------------------------------------- /Samples/MyType.ds: -------------------------------------------------------------------------------- 1 | many System 2 | 3 | [such Serializable] 4 | much MyType 5 | very MyType many int x int y much public 6 | data so x; 7 | moreData so y; 8 | 9 | such data so int much readonly 10 | such moreData so int much readonly much static 11 | 12 | very Method so long much public 13 | amaze so op data + moreData; 14 | 15 | very Helper so void much static 16 | wow "helper method"; -------------------------------------------------------------------------------- /Samples/Samples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8CD963C3-9DCD-4854-A3EA-970B94F2E488} 8 | Library 9 | Properties 10 | Samples 11 | Samples 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | cd ..\..\ 61 | build.bat 62 | 63 | 70 | -------------------------------------------------------------------------------- /Samples/Server.ds: -------------------------------------------------------------------------------- 1 | many System 2 | many System.Threading.Tasks 3 | many Servya 4 | 5 | [such Service] 6 | much DogeService 7 | [such Route] 8 | very WowAsAService so string much public 9 | amaze "wow"; 10 | 11 | very SlowWow so Task much public much async 12 | to the moon plz Task.Delay many 1000; 13 | amaze "wow"; 14 | 15 | much Program 16 | very Main so void much static 17 | such resolver gimme DependencyResolver; 18 | such router gimme Router; 19 | such parser gimme Parser; 20 | such autoRouter gimme AutoRouter many router parser resolver; 21 | plz autoRouter.Discover; 22 | such listener gimme AsyncHttpListener many router 1337 0; 23 | plz listener.Start many CreateLoop 1; 24 | plz Console.ReadLine; 25 | 26 | very CreateLoop so EventLoopContext much static 27 | amaze gimme EventLoopContext; -------------------------------------------------------------------------------- /Samples/WinForms.ds: -------------------------------------------------------------------------------- 1 | many System 2 | many System.Windows.Forms 3 | 4 | much DogeForm so Form 5 | very Main so void much static 6 | plz Application.EnableVisualStyles; 7 | plz Application.Run many gimme DogeForm; 8 | 9 | very DogeForm 10 | such button gimme Button; 11 | button.Text so "much click"; 12 | button.Click much handled MyClickHandler; 13 | plz Controls.Add many button; 14 | 15 | very MyClickHandler so void many object s EventArgs e 16 | plz MessageBox.Show many "many click"; 17 | 18 | very OnMouseClick so void many MouseEventArgs e much protected much override 19 | plz base.OnMouseClick many e; -------------------------------------------------------------------------------- /Samples/build.bat: -------------------------------------------------------------------------------- 1 | set dsc="..\DogeSharp\bin\Debug\dsc" 2 | 3 | xcopy /y Libs\*.dll 4 | 5 | echo Building console sample 6 | %dsc% Main.ds MyType.ds /out:ConsoleApp.exe /preservetranslated 7 | 8 | echo Building WinForms sample 9 | %dsc% WinForms.ds /target:winexe /out:FormsApp.exe /reference:System.Windows.Forms.dll /reference:System.dll /preservetranslated 10 | 11 | echo Building Servya sample 12 | %dsc% Server.ds /out:ServyaApp.exe /reference:Libs\Servya.dll /reference:Libs\Servya.Http.dll /reference:System.dll /preservetranslated 13 | -------------------------------------------------------------------------------- /Samples/build.sh: -------------------------------------------------------------------------------- 1 | dsc="mono ../DogeSharp/bin/Debug/dsc.exe" 2 | 3 | cp Libs/*.dll . 4 | 5 | echo Building console sample 6 | $dsc Main.ds MyType.ds /out:ConsoleApp.exe /preservetranslated 7 | 8 | echo Building WinForms sample 9 | $dsc WinForms.ds /target:winexe /out:FormsApp.exe /reference:System.Windows.Forms.dll /reference:System.dll /preservetranslated 10 | 11 | echo Building Servya sample 12 | $dsc Server.ds /out:ServyaApp.exe /reference:Libs/Servya.dll /reference:Libs/Servya.Http.dll /reference:System.dll /preservetranslated 13 | 14 | -------------------------------------------------------------------------------- /licence: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/returnString/DogeSharp/cbb9af3aed3cdff040a1dbf8c5182dded754fa3b/licence -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # D# (DogeSharp) 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/7qcm1amm8nuwd9k3)](https://ci.appveyor.com/project/returnString/dogesharp) 4 | 5 | D# is a programming language for Doge fans. 6 | 7 | *Huge disclaimer: I have no idea what I'm doing, and definitely shouldn't write languages.* 8 | 9 | You can shout ideas at me on Twitter: [@returnString](https://twitter.com/returnString) 10 | 11 | People have asked for a Dogecoin donation address, so I set this up: DAvLTZVRz9zg3wWjU5BbkjRR5ojnLJsunG 12 | 13 | ``` 14 | many System 15 | 16 | much MyClass 17 | very MyClass many int x much public 18 | data so x; 19 | 20 | such data so int much readonly 21 | 22 | much Program 23 | very Main so void much static 24 | such rand gimme Random; 25 | such x plz rand.Next; 26 | wow x; 27 | 28 | such instance gimme MyClass many 1; 29 | wow instance.data; 30 | 31 | ``` 32 | 33 | # Language 34 | ## Constructs 35 | * `many ` - using statement for namespace 36 | * `much ...` - declare a type 37 | * `very so [many ] [much ]` - declare a method 38 | * `very [much ]` - declare a constructor 39 | * `such ;` - declare and assign a local variable 40 | * `plz [many ]` - call a method 41 | * `so maths ` - use mathematical operators 42 | * `wow ;` - print to console 43 | * `amaze ;` - return a value 44 | 45 | # Usage 46 | ## Compiling .ds files 47 | Files with a ds extension are considered D# files. We use the `dsc` command-line tool (D# compiler) to convert these to either a .NET executable or DLL. 48 | 49 | `dsc.exe /target:exe /out:MyProgram.exe MyProgram.ds` 50 | 51 | `dsc` currently uses a translation step to generate .NET code, by converting .ds files into .cs files for the C# compiler behind the scenes. To see the generated files, use the /PreserveTranslated command-line option. 52 | 53 | # Building 54 | ## Dependencies 55 | * ANTLR v4 (Nuget) 56 | * Java v1.6+ 57 | 58 | ## From source 59 | `git clone https://github.com/returnString/DogeSharp.git` 60 | 61 | Windows: Open the solution in VS and build, or use MSBuild from cmd. 62 | Unix: Use build_grammar.sh to generate the necessary ANTLR files from the grammar, then build the project inside Xamarin Studio or use xbuild from a terminal. 63 | 64 | The build process first takes DogeSharp.csproj and outputs the `dsc` tool. Then, we invoke `dsc` for the sample projects as specified in build.bat/sh. This way, we can test the entire process from inside VS. 65 | --------------------------------------------------------------------------------