Initial commit of main compiler sources (or should I say ... SAUCES!)

This commit is contained in:
2025-06-08 23:58:21 +10:00
parent 60c566025c
commit 06f2613083
214 changed files with 22210 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
package slangc.model.clauses;
import slangc.api.BytecodeInstructionWriter;
import slangc.bytecode.MethodSignature;
import slangc.bytecode.TypeSignature;
import slangc.model.ExpressionModel;
import slangc.model.ExpressionOwner;
import slangc.model.InnerTypeScope;
import slangc.model.MemberModel;
import slangc.model.MethodModel;
import slangc.model.ParameterSet;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.parser.Branch;
import slangc.parser.Node;
public class Arguments extends Expressions implements ExpressionOwner {
public Arguments(ExpressionOwner owner, Branch source) {
super(owner, (Branch)source.getSubnode(1));
// TODO Auto-generated constructor stub
}
@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
public void generate(BytecodeInstructionWriter w, MethodModel method, boolean allowVarargs) {
ParameterSet params = method.getParameters();
for (int i = 0; i < params.countNonVarargParameters(); i++) {
ExpressionModel e = getExpression(i);
TypeSignature et = e.generate(w);
if (!et.mappableEquals(params.getParameter(i).getStorageType().getTypeSignature())) {
w.genConvert(et, params.getParameter(i).getStorageType().getTypeSignature());
}
}
if (!allowVarargs ||
(params.isVarargs()
&& params.countParameters() == countExpressions()
&& getExpression(params.countNonVarargParameters()).getResult()
.getValueTypeWithNullType(params.getVarargsParameter().getStorageType()).getTypeSignature()
== params.getVarargsParameter().getStorageType().getTypeSignature())) {
ExpressionModel e = getExpression(params.countNonVarargParameters());
TypeSignature et = e.generate(w);
if (!et.mappableEquals(params.getParameter(params.countNonVarargParameters()).getStorageType().getTypeSignature())) {
w.genConvert(et, params.getParameter(params.countNonVarargParameters()).getStorageType().getTypeSignature());
}
} else if (allowVarargs && params.isVarargs()) {
TypeSignature arrtype = params.getVarargsParameter().getStorageType().getTypeSignature();
w.genConst(w.getTarget().getHeap().getConstInt32("" + (countExpressions() - params.countNonVarargParameters())));
w.genNewArray(arrtype);
for (int i = params.countNonVarargParameters(); i < countExpressions(); i++) {
w.genDup(arrtype);
ExpressionModel e = getExpression(i);
TypeSignature et = e.generate(w);
if (!et.mappableEquals(params.getVarargsElementType().getTypeSignature())) {
w.genConvert(et, params.getVarargsElementType().getTypeSignature());
et = params.getVarargsElementType().getTypeSignature();
}
w.genSwap(et, arrtype);
w.genConst(w.getTarget().getHeap().getConstInt32("" + (i - params.countNonVarargParameters())));
//w.genSwap(getSystem().getDefaultInt32Type().getTypeSignature(), getResult().getValueType().getTypeSignature());
w.genArrayStore(params.getVarargsElementType().getTypeSignature());
}
}
}
}

View File

@@ -0,0 +1,75 @@
package slangc.model.clauses;
import slangc.api.Reporter;
import slangc.model.ClauseModel;
import slangc.model.InnerTypeScope;
import slangc.model.LocalVariableSlot;
import slangc.model.MemberModel;
import slangc.model.MethodModel;
import slangc.model.Named;
import slangc.model.StatementModel;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.parser.Branch;
import slangc.parser.Node;
public class CatchClause extends ClauseModel implements StatementOwner {
private Variables variables;
private StatementModel innerStatement;
public CatchClause(StatementOwner owner, Branch source) {
super(owner, source);
// TODO: Handle catch parameter...
//sourceFile.annotate(ErrorType.INTERNAL_ERROR, "TODO: Finish catch clause");
variables = (Variables) ClauseModel.construct(this, ((Branch)((Branch)source.getSubnode(1)).getSubnode(1)).getSubnode(0));
innerStatement = StatementModel.construct(this, source.getSubnode(2));
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> Catch:");
variables.dump(reporter, indent + incr, incr);
innerStatement.dump(reporter, indent + incr, incr);
}
@Override
public int resolveExpressions() {
return variables.resolveExpressions() + innerStatement.resolveExpressions();
}
//@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
//@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
//@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
@Override
public Named lookupSimpleName(String name) {
if (variables.hasVariable(name)) {
return variables.getVariable(name);
}
return super.lookupSimpleName(name);
}
public StatementModel getInnerStatement() {
return innerStatement;
}
public LocalVariableSlot getCatchVariable() {
return variables.getVariable(0);
}
public TypeModel getCatchType() {
return variables.getVariable(0).getStorageType();
}
}

View File

@@ -0,0 +1,51 @@
package slangc.model.clauses;
import slangc.api.Reporter;
import slangc.model.ClauseModel;
import slangc.model.InnerTypeScope;
import slangc.model.MemberModel;
import slangc.model.StatementModel;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.parser.Branch;
import slangc.parser.Node;
public class ElseClause extends ClauseModel implements StatementOwner {
private StatementModel innerStatement;
public ElseClause(StatementOwner owner, Branch source) {
super(owner, source);
innerStatement = StatementModel.construct(this, source.getSubnode(1));
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> Else:");
innerStatement.dump(reporter, indent + incr, incr);
}
@Override
public int resolveExpressions() {
return innerStatement.resolveExpressions();
}
//@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
//@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
//@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
public StatementModel getInnerStatement() {
return innerStatement;
}
}

View File

@@ -0,0 +1,106 @@
package slangc.model.clauses;
import slang.data.List;
import slangc.api.Reporter;
import slangc.model.ExpressionModel;
import slangc.model.ExpressionOwner;
import slangc.model.InnerTypeScope;
import slangc.model.MemberModel;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.parser.Branch;
import slangc.parser.Node;
import slangc.parser.NodeType;
public class Expressions extends ExpressionsOrVariables implements ExpressionOwner {
private List<ExpressionModel> exprs = new List<ExpressionModel>();
public Expressions(ExpressionOwner owner, Branch source) {
super(owner, source);
for (int i = 0; i < source.countSubnodes(); i++) {
Node n = source.getSubnode(i);
if (n.getNodeType() != NodeType.COMMA) {
exprs.append(ExpressionModel.construct(this, n));
}
}
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> Expressions:");
// do not recurse: type.dump(reporter, indent + incr, incr);
for (int i = 0; i < exprs.count(); i++) {
exprs.get(i).dump(reporter, indent + incr, incr);
}
}
@Override
public int resolveExpressions() {
int nresolved = 0;
for (int i = 0; i < exprs.count(); i++) {
nresolved += exprs.get(i).resolveExpressions();
}
return nresolved;
}
//@Override
public TypeModel getExpectedResult(ExpressionModel e) {
return getOwner().getExpectedResult(e);
}
//@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
//@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
//@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
@Override
public ExpressionOwner getOwner() {
// TODO Auto-generated method stub
return (ExpressionOwner) super.getOwner();
}
//@Override
public ExpressionModel[] getSubexpressions() {
ExpressionModel[] result = new ExpressionModel[exprs.count()];
for (int i = 0; i < result.length; i++) {
result[i] = exprs.get(i);
}
return result;
}
public String resultString() {
String r = "(";
for (int i = 0; i < exprs.count(); i++) {
if (i != 0) {
r += ",";
}
r += exprs.get(i).getResult();
}
return r + ")";
}
public int countExpressions() {
return exprs.count();
}
public ExpressionModel getExpression(int i) {
return exprs.get(i);
}
}

View File

@@ -0,0 +1,16 @@
package slangc.model.clauses;
import slangc.model.ClauseModel;
import slangc.model.StatementOwner;
import slangc.parser.Branch;
/** Used as an internal clause primarily in "for" statements where the parts inside (...;...;...) might be
* variable definitions or might be plain old expressions (or might just be empty, i.e. zero expressions).
*/
public abstract class ExpressionsOrVariables extends ClauseModel {
public ExpressionsOrVariables(StatementOwner owner, Branch source) {
super(owner, source);
}
}

View File

@@ -0,0 +1,52 @@
package slangc.model.clauses;
import slangc.api.Reporter;
import slangc.model.ClauseModel;
import slangc.model.InnerTypeScope;
import slangc.model.MemberModel;
import slangc.model.StatementModel;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.parser.Branch;
import slangc.parser.Node;
public class FinallyClause extends ClauseModel implements StatementOwner {
private StatementModel innerStatement;
public FinallyClause(StatementOwner owner, Branch source) {
super(owner, source);
innerStatement = StatementModel.construct(this, source.getSubnode(1));
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> Finally:");
innerStatement.dump(reporter, indent + incr, incr);
}
@Override
public int resolveExpressions() {
return innerStatement.resolveExpressions();
}
//@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
//@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
//@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
public StatementModel getInnerStatement() {
return innerStatement;
}
}

View File

@@ -0,0 +1,95 @@
package slangc.model.clauses;
import slang.data.List;
import slangc.api.Reporter;
import slangc.model.ClauseModel;
import slangc.model.InnerTypeScope;
import slangc.model.MemberModel;
import slangc.model.Named;
import slangc.model.StatementModel;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.model.InnerTypeScope.SourceScope;
import slangc.model.statements.VariableStatement;
import slangc.parser.Branch;
import slangc.parser.Node;
import slangc.parser.NodeType;
public class SwitchMembers extends ClauseModel implements StatementOwner {
private List<StatementModel> statements = new List<StatementModel>();
private InnerTypeScope.SourceScope typeScope;
public SwitchMembers(StatementOwner owner, Branch source) {
super(owner, source);
for (int i = 0; i < source.countSubnodes(); i++) {
if (source.getSubnode(i).getNodeType() != NodeType.SEMICOLON) {
statements.append(StatementModel.construct(this, source.getSubnode(i)));
}
}
typeScope = owner.getTypeScope().getInnerScopeForSource(source);
}
//@Override
public InnerTypeScope getTypeScope() {
return typeScope == null ? getOwner().getTypeScope() : typeScope;
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> Switch members:");
for (int i = 0; i < statements.count(); i++) {
StatementModel s = statements.get(i);
s.dump(reporter, indent + incr, incr);
}
}
@Override
public int resolveExpressions() {
int nresolved = 0;
for (int i = 0; i < statements.count(); i++) {
StatementModel s = statements.get(i);
nresolved += s.resolveExpressions();
}
return nresolved;
}
//@Override
public TypeModel resolveType(Node subnode) {
return getTypeScope().resolveTypeReference(subnode);
}
//@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
@Override
public Named lookupSimpleName(String name) {
for (int i = 0; i < statements.count(); i++) {
StatementModel s = statements.get(i);
if (s instanceof VariableStatement) {
VariableStatement vs = (VariableStatement) s;
if (vs.hasVariable(name)) {
return vs.getVariable(name);
}
}
}
if (typeScope != null) {
if (typeScope.hasInnerType(name)) {
return typeScope.getInnerType(name);
}
}
return super.lookupSimpleName(name);
}
public int countMembers() {
return statements.count();
}
public StatementModel getMember(int i) {
return statements.get(i);
}
}

View File

@@ -0,0 +1,25 @@
package slangc.model.clauses;
import slangc.api.Reporter;
import slangc.model.ClauseModel;
import slangc.model.StatementOwner;
import slangc.parser.ErrorType;
import slangc.parser.Node;
public class UnrecognisedClause extends ClauseModel {
public UnrecognisedClause(StatementOwner owner, Node source) {
super(owner, source);
source.annotate(ErrorType.INTERNAL_ERROR, "Unrecognised clause type " + source.getNodeType() + " (Internal error/TODO)");
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> TODO: Unrecognised clause (" + getSource().getNodeType() + ")");
}
@Override
public int resolveExpressions() {
return 0;
}
}

View File

@@ -0,0 +1,94 @@
package slangc.model.clauses;
import slang.data.List;
import slangc.api.Reporter;
import slangc.model.InnerTypeScope;
import slangc.model.LocalVariableSlot;
import slangc.model.MemberModel;
import slangc.model.Named;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.parser.Branch;
import slangc.parser.Node;
import slangc.parser.NodeType;
public class Variables extends ExpressionsOrVariables implements StatementOwner {
private TypeModel type;
private List<LocalVariableSlot> slots = new List<LocalVariableSlot>();
public Variables(StatementOwner owner, Branch source) {
super(owner, source);
type = owner.resolveType(source.getSubnode(1));
if (type == null)
return;
Branch l = (Branch) source.getSubnode(2);
if (l.getNodeType() == NodeType.NAME || l.getNodeType() == NodeType.INDEXED_NAME) {
slots.append(new LocalVariableSlot(this, l, type));
} else {
for (int i = 0; i < l.countSubnodes(); i++) {
slots.append(new LocalVariableSlot(this, (Branch)l.getSubnode(i), type));
}
}
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> Variables:");
// do not recurse: type.dump(reporter, indent + incr, incr);
for (int i = 0; i < slots.count(); i++) {
slots.get(i).dump(reporter, indent + incr, incr);
}
}
@Override
public int resolveExpressions() {
int nresolved = 0;
for (int i = 0; i < slots.count(); i++) {
nresolved += slots.get(i).resolveExpressions();
}
return nresolved;
}
//@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
//@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
//@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
public boolean hasVariable(String name) {
for (int i = 0; i < slots.count(); i++) {
if (slots.get(i).getName().equals(name)) {
return true;
}
}
return false;
}
public Named getVariable(String name) {
for (int i = 0; i < slots.count(); i++) {
if (slots.get(i).getName().equals(name)) {
return slots.get(i);
}
}
return null;
}
public int countVariables() {
return slots.count();
}
public LocalVariableSlot getVariable(int i) {
return slots.get(i);
}
}