Skip to content

Commit

Permalink
Begin work on C# AST, increment to v0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
SomeRanDev committed Feb 22, 2024
1 parent be746fc commit 9c17288
Show file tree
Hide file tree
Showing 16 changed files with 366 additions and 32 deletions.
2 changes: 1 addition & 1 deletion haxelib.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "csharp",
"version": "0.1.0",
"version": "0.2.0",
"description": "A remake of the Haxe/C# target written entirely within Haxe using Reflaxe.",
"url": "https://github.com/RobertBorghese/reflaxe.CSharp",
"license": "MIT",
Expand Down
57 changes: 39 additions & 18 deletions src/cscompiler/CSCompiler.hx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import haxe.macro.Type;
// ---

import reflaxe.BaseCompiler;
import reflaxe.DirectToStringCompiler;
import reflaxe.GenericCompiler;
import reflaxe.data.ClassVarData;
import reflaxe.data.ClassFuncData;
import reflaxe.data.EnumOptionData;
import reflaxe.helpers.Context;
import reflaxe.output.DataAndFileInfo;
import reflaxe.output.StringOrBytes;

using reflaxe.helpers.SyntaxHelper;
using reflaxe.helpers.ModuleTypeHelper;
Expand All @@ -26,6 +28,10 @@ using reflaxe.helpers.TypeHelper;

// ---

import cscompiler.ast.CSClass;
import cscompiler.ast.CSEnum;
import cscompiler.ast.CSStatement;
import cscompiler.ast.CSType;
import cscompiler.components.*;
import cscompiler.config.Define;

Expand All @@ -34,7 +40,7 @@ import cscompiler.config.Define;
Its "impl" functions are called from Reflaxe.
**/
class CSCompiler extends reflaxe.DirectToStringCompiler {
class CSCompiler extends reflaxe.GenericCompiler<CSClass, CSEnum, CSStatement> {
/**
The namespace used for top-level module types.
**/
Expand All @@ -43,22 +49,22 @@ class CSCompiler extends reflaxe.DirectToStringCompiler {
/**
Handles implementation of `compileClassImpl`.
**/
public var classComp(default, null): CSClass;
public var classComp(default, null): CSCompiler_Class;

/**
Handles implementation of `compileEnumImpl`.
**/
public var enumComp(default, null): CSEnum;
public var enumComp(default, null): CSCompiler_Enum;

/**
Handles implementation of `compileExprImpl`.
**/
public var exprComp(default, null): CSExpression;
public var exprComp(default, null): CSCompiler_Expr;

/**
Handles implementation of `compileType`, `compileModuleType`, and `compileClassName`.
**/
public var typeComp(default, null): CSType;
public var typeComp(default, null): CSCompiler_Type;

/**
Constructor.
Expand All @@ -77,10 +83,10 @@ class CSCompiler extends reflaxe.DirectToStringCompiler {
// Bypass Haxe null-safety not allowing `this` usage.
@:nullSafety(Off) var self = this;

classComp = new CSClass(self);
enumComp = new CSEnum(self);
exprComp = new CSExpression(self);
typeComp = new CSType(self);
classComp = new CSCompiler_Class(self);
enumComp = new CSCompiler_Enum(self);
exprComp = new CSCompiler_Expr(self);
typeComp = new CSCompiler_Type(self);
}

// ---
Expand All @@ -106,7 +112,11 @@ class CSCompiler extends reflaxe.DirectToStringCompiler {
function setupMainFunction() {
final mainExpr = getMainExpr();
if(mainExpr != null) {
final csCode = compileExpressionOrError(mainExpr);
final csExpr = compileExpressionOrError(mainExpr);

// TODO: Convert `csExpr` to `String` using printer
final csCode = "";

appendToExtraFile(BootFilename, haxeBootContent(csCode));
}
}
Expand Down Expand Up @@ -177,25 +187,36 @@ namespace Haxe {
}

/**
Required for adding semicolons at the end of each line. Overridden from Reflaxe.
Generate output.
TODO.
**/
override function formatExpressionLine(expr: String): String {
return expr + ";";
public function generateOutputIterator(): Iterator<DataAndFileInfo<StringOrBytes>> {
// TODO: Print all classes and enums using these vars from `GenericCompiler`:
// var classes: Array<CSClass>
// var enums: Array<CSEnum>

return {
hasNext: () -> false,
next: () -> {
return new DataAndFileInfo(StringOrBytes.fromString(""), @:nullSafety(Off) null, null, null);
}
};
}

// ---

/**
Generate the C# output given the Haxe class information.
**/
public function compileClassImpl(classType: ClassType, varFields: Array<ClassVarData>, funcFields: Array<ClassFuncData>): Null<String> {
public function compileClassImpl(classType: ClassType, varFields: Array<ClassVarData>, funcFields: Array<ClassFuncData>): Null<CSClass> {
return classComp.compile(classType, varFields, funcFields);
}

/**
Generate the C# output given the Haxe enum information.
**/
public function compileEnumImpl(enumType: EnumType, options: Array<EnumOptionData>): Null<String> {
public function compileEnumImpl(enumType: EnumType, options: Array<EnumOptionData>): Null<CSEnum> {
return enumComp.compile(enumType, options);
}

Expand All @@ -206,7 +227,7 @@ namespace Haxe {
A `Position` is provided so compilation errors can be reported to it.
**/
public function compileType(type: Type, pos: Position): String {
public function compileType(type: Type, pos: Position): CSType {
final result = typeComp.compile(type, pos);
if(result == null) {
throw "Type could not be generated: " + Std.string(type);
Expand Down Expand Up @@ -253,7 +274,7 @@ namespace Haxe {
/**
Generate the C# output given the Haxe typed expression (`TypedExpr`).
**/
public function compileExpressionImpl(expr: TypedExpr, topLevel: Bool): Null<String> {
public function compileExpressionImpl(expr: TypedExpr, topLevel: Bool): Null<CSStatement> {
return exprComp.compile(expr, topLevel);
}

Expand Down
26 changes: 26 additions & 0 deletions src/cscompiler/ast/CSClass.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cscompiler.ast;

#if (macro || cs_runtime)

/**
Represents a class in C#.
TODO.
**/
class CSClass {
public var name(default, null): String;

var superClass: Null<CSClass>;
var superClassTypeParams: Null<Array<CSType>>;

public function new(name: String) {
this.name = name;
}

public function setSuperClass(superClass: CSClass, typeParams: Array<CSType>) {
this.superClass = superClass;
superClassTypeParams = typeParams;
}
}

#end
28 changes: 28 additions & 0 deletions src/cscompiler/ast/CSConstant.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cscompiler.ast;

#if (macro || cs_runtime)

/**
Represents a constant expression.
TODO: Give each case a better description.
**/
enum CSConstant {
CSInt(i: Int, suffix: String);

/**
TODO:
Should there be a `CSDouble`?
Or some better way to handle differen suffixes?
**/
CSFloat(s: String, suffix: String);

CSString(s: String);
CSBool(b: Bool);

CSNull;
CSThis;
CSSuper;
}

#end
18 changes: 18 additions & 0 deletions src/cscompiler/ast/CSEnum.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cscompiler.ast;

#if (macro || cs_runtime)

/**
Represents an enum in C#.
TODO.
**/
class CSEnum {
public var name(default, null): String;

public function new(name: String) {
this.name = name;
}
}

#end
101 changes: 101 additions & 0 deletions src/cscompiler/ast/CSExpr.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package cscompiler.ast;

#if (macro || cs_runtime)

import haxe.macro.Expr;
import haxe.macro.Type;

/**
Represents a C# expression.
**/
class CSExpr {
public var def(default, null): CSExprDef;
public var haxeExpr(default, null): Null<TypedExpr>;

public function new(def: CSExprDef, haxeExpr: Null<TypedExpr> = null) {
this.def = def;
this.haxeExpr = haxeExpr;
}
}

/**
TODO: Give each case a better description.
**/
enum CSExprDef {
/**
A constant.
**/
CSConst(constant: CSConstant);

/**
Reference to a local variable `varData`.
**/
CSLocalVar(varData: CSVar);

/**
Array access `baseExpr[indexExpr]`.
**/
CSArray(baseExpr: CSExpr, indexExpr: CSExpr);

/**
Binary operator `leftExpr op rightExpr`.
**/
CSBinop(op: Binop, leftExpr: CSExpr, rightExpr: CSExpr);

/**
Field access on `e` of name `fieldName`.
TODO:
Replace `fieldName: String` with a custom `FieldAccess` type (`fieldAccess: CSFieldAccess`)?
**/
CSField(e: CSExpr, fieldName: String);

/**
Reference to a module type `m`.
TODO:
This is assuming static-access is only possible from a class in C#?
Maybe this should be replaced with a `CSStaticVar(varData: CSVar, cls: CSClass)`.
**/
CSClassExpr(cls: CSClass);

/**
Parentheses `(e)`.
**/
CSParenthesis(e: CSExpr);

/**
An array declaration `{ expressions }`.
**/
CSArrayDecl(expressions: Array<CSExpr>);

/**
A call `baseExpr<typeParams>(arguments)`.
**/
CSCall(baseExpr: CSExpr, typeParams: Array<CSType>, arguments: Array<CSExpr>);

/**
A constructor call `new cls<typeParams>(arguments)`.
**/
CSNew(cls: CSClass, typeParams: Array<CSType>, arguments: Array<CSExpr>);

/**
An unary operator `op` on `baseExpr`.
TODO:
Is postfix necessary?
**/
CSUnop(op: Unop, postFix: Bool, baseExpr: CSExpr);

/**
A function declaration.
**/
CSFunctionExpr(tfunc: CSFunction);

/**
An unknown identifier.
**/
CSIdent(s: String);
}

#end
13 changes: 13 additions & 0 deletions src/cscompiler/ast/CSFunction.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cscompiler.ast;

#if (macro || cs_runtime)

/**
Represents a function in C#.
TODO.
**/
class CSFunction {
}

#end
38 changes: 38 additions & 0 deletions src/cscompiler/ast/CSStatement.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cscompiler.ast;

#if (macro || cs_runtime)

import haxe.macro.Type;

/**
Represents a C# statement.
**/
class CSStatement {
public var def(default, null): CSStatementDef;
public var haxeExpr(default, null): Null<TypedExpr>;

public function new(def: CSStatementDef, haxeExpr: Null<TypedExpr> = null) {
this.def = def;
this.haxeExpr = haxeExpr;
}
}

enum CSStatementDef {
CSExprStatement(expression: CSExpr);

CSBlock(statements: Array<CSStatement>);

/**
TODO: else if
**/
CSIf(condition: CSExpr, ifContent: Array<CSStatement>, elseContent: Null<Array<CSStatement>>);

CSWhile(condition: CSExpr, content: Array<CSStatement>, normalWhile: Bool);

/**
A variable declaration `var varData` or `var varData = expr`.
**/
CSVar(varData: CSVar, expr: Null<CSExpr>);
}

#end
Loading

0 comments on commit 9c17288

Please sign in to comment.