Skip to content

Commit

Permalink
Add C# type in CSExpr (because we can know it from haxe TypedExpr
Browse files Browse the repository at this point in the history
… and it can be definitely useful). WIP TObjectDecl and TArrayDecl
  • Loading branch information
jeremyfa committed Mar 16, 2024
1 parent 97ad1ac commit 3d082c8
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 13 deletions.
8 changes: 5 additions & 3 deletions src/cscompiler/ast/CSExpr.hx
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ import haxe.macro.Expr;
import haxe.macro.Type;

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

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

Expand Down Expand Up @@ -73,7 +75,7 @@ enum CSExprDef {
/**
A constructor call `new cls<typeParams>(arguments)`.
**/
CSNew(cls: CSClass, typeParams: Array<CSType>, arguments: Array<CSExpr>);
CSNew(cls: CSTypePath, typeParams: Array<CSType>, arguments: Array<CSExpr>);

/**
An unary operator `op` on `baseExpr`.
Expand Down
63 changes: 53 additions & 10 deletions src/cscompiler/components/CSCompiler_Expr.hx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cscompiler.components;

import cscompiler.ast.CSType;
import cscompiler.ast.CSConstant;
import cscompiler.ast.CSExpr;
#if (macro || cs_runtime)
Expand Down Expand Up @@ -59,32 +60,39 @@ class CSCompiler_Expr extends CSCompiler_Base {
Implementation of `CSCompiler.compileExpressionImpl`.
**/
public function compile(expr: TypedExpr, topLevel: Bool): Null<CSStatement> {

final csType:Null<CSType> = expr.t != null ? compiler.compileType(expr.t, expr.pos) : null;

return switch(expr.expr) {
case TConst(constant): {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSConst(compileConstant(constant))
})
}
case TLocal(v): {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSIdent(compiler.compileVarName(v.name, expr))
})
}
case TIdent(s): {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSIdent(compiler.compileVarName(s, expr))
})
}
case TArray(e1, e2): {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSArray(
csStatementToExpr(_compileExpression(e1)),
csStatementToExpr(_compileExpression(e2))
Expand All @@ -95,6 +103,7 @@ class CSCompiler_Expr extends CSCompiler_Base {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSBinop(
op,
csStatementToExpr(_compileExpression(e1)),
Expand All @@ -107,6 +116,7 @@ class CSCompiler_Expr extends CSCompiler_Base {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: switch fa {
case FInstance(c, params, cf):
CSField(
Expand Down Expand Up @@ -161,54 +171,87 @@ class CSCompiler_Expr extends CSCompiler_Base {
// Note:
// we don't have access to type params here,
// so they are always empty.
// TODO: or can we resolve them from the expression type?
switch m {
case TClassDecl(c):
{
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSTypeExpr(compiler.compileType(TInst(c, []), expr.pos))
})
}
case TEnumDecl(e): {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSTypeExpr(compiler.compileType(TEnum(e, []), expr.pos))
})
}
case TTypeDecl(t): {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSTypeExpr(compiler.compileType(TType(t, []), expr.pos))
})
}
case TAbstract(a): {
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSTypeExpr(compiler.compileType(TAbstract(a, []), expr.pos))
})
}
}
}
/*
case TParenthesis(e): {
final csExpr = _compileExpression(e);
result = if(!EverythingIsExprSanitizer.isBlocklikeExpr(e)) {
"(" + csExpr + ")";
} else {
csExpr;
}
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSParenthesis(csStatementToExpr(_compileExpression(e)))
})
}
// We are generating the same as original C# target here
case TObjectDecl(fields): {
// TODO: Anonymous structure expression?
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSNew(
"haxe.lang.DynamicObject",
[],
[] // TODO fields
)
})
}
// We are generating the same as original C# target here too:
// an dedicated Array type specific to Haxe so that it can
// work the same as haxe arrays in general
case TArrayDecl(el): {
// TODO: Array expression?
// result = "new type[] {" + el.map(e -> _compileExpression(e)).join(", ") + "}";
// TODO resolve array element type correctly. Need to test
// if haxe is providing correct expression type to the array decl
// typed expression in that situation:
// var array = []; <- does haxe provide `Int` as type param on the type here
// array[0] = 1;
{
haxeExpr: expr,
def: CSExprStatement({
haxeExpr: expr,
type: csType,
def: CSNew(
"Array",
[],
[] // TODO elements
)
})
}
}
/*
case TCall(e, el): {
// Check for @:nativeFunctionCode (built-in Reflaxe feature)
final nfc = compiler.compileNativeFunctionCodeMeta(e, el);
Expand Down

0 comments on commit 3d082c8

Please sign in to comment.