Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Translate Op to C# (part 1)
  • Loading branch information
sorear committed May 31, 2012
1 parent eb41510 commit 81ba7c1
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -8,7 +8,7 @@ CP=cp

cskernel=Kernel.cs Builtins.cs Cursor.cs JSYNC.cs NieczaCLR.cs Utils.cs \
ObjModel.cs BigInteger.cs Printf.cs CodeGen.cs CClass.cs \
GeneratedTrigFunctions.cs Serialize.cs UCD.cs CgOp.cs
GeneratedTrigFunctions.cs Serialize.cs UCD.cs CgOp.cs Op.cs

# Tell make to regard the following targets as not being filenames
.PHONY: all aot test spectest clean realclean
Expand Down
20 changes: 10 additions & 10 deletions lib/CgOp.cs
Expand Up @@ -538,14 +538,14 @@ public static CgOp @double(params object[] kids)

// cc_expr

static CgOp process_arglist(string kind, object a1, object a2,
object[] raw) {
static CgOp process_arglist(string kind, object[] raw) {
var meth = kind == "methodcall";
var bits = new List<object>();
var sig = new StringBuilder();
bits.Add(a1);
bits.Add(meth ? raw[1] : raw[0]);
bits.Add(null); // sig space
if (a2 != null) bits.Add(a2);
int ix = 0;
if (meth) bits.Add(raw[0]);
int ix = meth ? 2 : 1;
while (ix < raw.Length) {
if (raw[ix] is CgOp) {
sig.Append((char) 0);
Expand All @@ -560,12 +560,12 @@ public static CgOp @double(params object[] kids)
return N(kind, bits.ToArray());
}

public static CgOp subcall(CgOp sub, params object[] args) {
return process_arglist("subcall", sub, null, args);
public static CgOp subcall(params object[] args) {
return process_arglist("subcall", args);
}

public static CgOp methodcall(CgOp self, object name, params object[] args) {
return process_arglist("methodcall", name, self, args);
public static CgOp methodcall(params object[] args) {
return process_arglist("methodcall", args);
}


Expand Down Expand Up @@ -601,7 +601,7 @@ public static CgOp @double(params object[] kids)

public class Test {
public static void Run() {
var c = CgOp.subcall(CgOp.corelex("&say"), CgOp.string_var("Hello, World"));
var c = CgOp.subcall(CgOp.corelex("&say"), CgOp.methodcall(CgOp.string_var("Hello, World"), "flip"));
Console.WriteLine(c);
}
}
Expand Down
132 changes: 132 additions & 0 deletions lib/Op.cs
@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;

using Niecza;
using Niecza.Compiler;

namespace Niecza.Compiler.Op {
abstract class Op {
Cursor pos;

protected Op(Cursor pos) { this.pos = pos; }

// These are just placeholders until more of the system is online
public int LineOf(Cursor c) { return 0; }
public void Sorry(Cursor c, string msg) { throw new NotImplementedException(); }

// replaces both zyg and ctxzyg
public virtual Op VisitOps(Func<Op,Op> post) { return post(this); }

public CgOp cgop(SubInfo body) {
if (pos != null) {
return CgOp.ann(LineOf(pos), code(body));
} else {
return code(body);
}
}

// minorly ick
public CgOp cgop_statement(SubInfo body) {
if (pos != null) {
return CgOp.ann(LineOf(pos), CgOp.statement(code(body)));
} else {
return CgOp.statement(code(body));
}
}

public CgOp cgop_labelled(SubInfo body, string label) {
if (pos != null) {
return CgOp.ann(LineOf(pos), code_labelled(body, label));
} else {
return code_labelled(body, label);
}
}

public virtual Op to_bind(Cursor at, bool ro, CgOp rhs) {
Sorry(at, "Cannot use bind operator with this LHS");
return new StatementList(null, new Op[0]);
}

protected abstract CgOp code(SubInfo body);
protected virtual CgOp code_labelled(SubInfo body, string label) {
return code(body);
}

public virtual Op statement_level(Cursor at) { return this; }
public virtual Op semilist_level(Cursor at) { return this; }
public virtual bool onlystub() { return false; }
public virtual Variable const_value(SubInfo body) { return null; }
}

class RawCgOp : Op {
object root;

public RawCgOp(Cursor c, object root_) : base(c) { root = root_; }

object dovisit(object node, Func<Op,Op> post) {
if (node is Op)
return ((Op)node).VisitOps(post);
object[] na = node as object[];
if (na != null)
for (int i = 0; i < na.Length; i++)
na[i] = dovisit(na[i], post);
return node;
}
public override Op VisitOps(Func<Op,Op> post) {
root = dovisit(root, post);
return post(this);
}

object code(object node, SubInfo body) {
if (node is Op) return ((Op)node).cgop(body);
object[] na = (object[])node;
if (na == null) return node;
object[] pna = new object[na.Length - 1];
for (int i = 1; i < na.Length; i++)
pna[i-1] = code(na[i], body);
string kind = (string)na[0];
if (kind == "subcall")
return CgOp.subcall(pna);
if (kind == "methodcall")
return CgOp.methodcall(pna);
if (kind == "rnull")
return CgOp.rnull((CgOp)pna[0]);
if (kind == "string_var")
return CgOp.string_var((string)pna[0]);
return CgOp.N(kind, pna);
}
protected override CgOp code(SubInfo body) {
return (CgOp)code(root, body);
}
}

class StatementList : Op {
Op[] children;
bool statement;
public StatementList(Cursor c, Op[] children, bool stmt = false) : base(c) {
this.children = children; statement = stmt;
}
public override Op VisitOps(Func<Op,Op> post) {
for (int i = 0; i < children.Length; i++)
children[i] = children[i].VisitOps(post);
return post(this);
}
public override bool onlystub() {
return children.Length == 1 && children[0].onlystub();
}
public override Variable const_value(SubInfo body) {
return children.Length == 1 ? children[0].const_value(body) : null;
}
protected override CgOp code(SubInfo body) {
if (children.Length == 0) return CgOp.corelex("Nil");
CgOp[] bits = new CgOp[children.Length];
for (int i = 0; i < bits.Length; i++) {
bits[i] = statement ? children[i].cgop_statement(body) :
children[i].cgop(body);
if (i < bits.Length - 1) bits[i] = CgOp.sink(bits[i]);
}
return CgOp.prog(bits);
}
}

}

0 comments on commit 81ba7c1

Please sign in to comment.