Skip to content

Commit

Permalink
Merge pull request #91 from tge-was-taken/jump
Browse files Browse the repository at this point in the history
Jump instruction support & make operands unsigned
  • Loading branch information
tge-was-taken authored Nov 28, 2024
2 parents 156ab34 + 406e7a9 commit d6c62d2
Show file tree
Hide file tree
Showing 44 changed files with 952 additions and 461 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ private short CalculateLocalIntVariableCount()
continue;
}

if (instruction.OperandShort > highestIndex)
highestIndex = instruction.OperandShort;
if (instruction.OperandUShort > highestIndex)
highestIndex = instruction.OperandUShort;
}
}

Expand All @@ -343,8 +343,8 @@ private short CalculateLocalFloatVariableCount()
continue;
}

if (instruction.OperandShort > highestIndex)
highestIndex = instruction.OperandShort;
if (instruction.OperandUShort > highestIndex)
highestIndex = instruction.OperandUShort;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public BinaryInstruction[] ReadTextSection(ref BinarySectionHeader sectionHeader
if (i != 0 && instructions[i - 1].Opcode == Opcode.PUSHI)
{
instruction.Opcode = unchecked((Opcode)(-1));
instruction.OperandInt = mReader.ReadInt32();
instruction.OperandUInt = mReader.ReadUInt32();
}
else if (i != 0 && instructions[i - 1].Opcode == Opcode.PUSHF)
{
Expand All @@ -161,8 +161,7 @@ public BinaryInstruction[] ReadTextSection(ref BinarySectionHeader sectionHeader
else
{
instruction.Opcode = (Opcode)mReader.ReadInt16();
if(instruction.Opcode == Opcode.COMM) { instruction.OperandUShort = mReader.ReadUInt16(); }
else { instruction.OperandShort = mReader.ReadInt16(); }
instruction.OperandUShort = mReader.ReadUInt16();
}

instructions[i] = instruction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ public void WriteTextSection(ref BinarySectionHeader sectionHeader, BinaryInstru
{
ref var instruction = ref instructions[i];

mWriter.Write((short)instruction.Opcode);
mWriter.Write(instruction.OperandShort);
mWriter.Write((ushort)instruction.Opcode);
mWriter.Write(instruction.OperandUShort);

// Write large operands immediately afterwards
if (instruction.Opcode == Opcode.PUSHI)
{
Trace.Assert(i + 1 < instructions.Length, "Missing operand value for PUSHI");
mWriter.Write(instructions[++i].OperandInt);
mWriter.Write(instructions[++i].OperandUInt);
}
else if (instruction.Opcode == Opcode.PUSHF)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,17 @@ public struct BinaryInstruction
// union
// {
public Opcode Opcode;
public short OperandShort;
public ushort OperandUShort;
// }

// union
// {
public int OperandInt;
public uint OperandUInt;
public float OperandFloat;
// }

public override string ToString()
{
return $"{Opcode} short: {OperandShort} ushort: {OperandUShort} int: {OperandInt} float: {OperandFloat}";
return $"{Opcode} ushort: {OperandUShort} int: {OperandUInt} float: {OperandFloat}";
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class LabelInfo
{
public string Name { get; set; }

public short Index { get; set; }
public ushort Index { get; set; }

public short InstructionIndex { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,8 @@ private bool TryParseFunctionDeclaration(FlowScriptParser.FunctionDeclarationSta
if (!TryGet(context, "Expected function index", context.IntLiteral, out var indexNode))
return false;

IntLiteral indexIntLiteral = null;
if (!TryFunc(indexNode, "Failed to parse function index", () => TryParseIntLiteral(indexNode, out indexIntLiteral)))
UIntLiteral indexIntLiteral = null;
if (!TryFunc(indexNode, "Failed to parse function index", () => TryParseUIntLiteral(indexNode, out indexIntLiteral)))
return false;

functionDeclaration.Index = indexIntLiteral;
Expand Down Expand Up @@ -584,7 +584,7 @@ private bool TryParseVariableDeclaration(FlowScriptParser.VariableDeclarationSta
{
// Parse size
var sizeLiteral = context.arraySignifier().IntLiteral();
if (!(sizeLiteral != null && TryParseIntLiteral(sizeLiteral, out var size)))
if (!(sizeLiteral != null && TryParseUIntLiteral(sizeLiteral, out var size)))
{
var arrayInitializer = variableDeclaration.Initializer as InitializerList;
if (arrayInitializer == null)
Expand All @@ -593,7 +593,7 @@ private bool TryParseVariableDeclaration(FlowScriptParser.VariableDeclarationSta
return false;
}

size = arrayInitializer.Expressions.Count;
size = (uint)arrayInitializer.Expressions.Count;
}

((ArrayVariableDeclaration)variableDeclaration).Size = size;
Expand Down Expand Up @@ -653,7 +653,7 @@ private bool TryParseVariableModifierIndex(FlowScriptParser.VariableModifierCont
{
if (TryGet(context, context.IntLiteral, out var indexNode))
{
if (!TryParseIntLiteral(indexNode, out var index))
if (!TryParseUIntLiteral(indexNode, out var index))
{
LogError(indexNode.Symbol, "Invalid variable index");
return false;
Expand Down Expand Up @@ -1480,6 +1480,37 @@ private bool TryParseIntLiteral(ITerminalNode node, out IntLiteral literal)
return true;
}

private bool TryParseUIntLiteral(ITerminalNode node, out UIntLiteral literal)
{
literal = CreateAstNode<UIntLiteral>(node);

uint value = 0;
string intString = node.Symbol.Text;

if (intString.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
{
// hex number
if (!uint.TryParse(intString.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out value))
{
LogError(node.Symbol, "Invalid hexidecimal integer value");
return false;
}
}
else
{
// assume decimal
if (!uint.TryParse(intString, out value))
{
LogError(node.Symbol, "Invalid decimal integer value");
return false;
}
}

literal.Value = value;

return true;
}

private bool TryParseFloatLiteral(ITerminalNode node, out FloatLiteral literal)
{
literal = CreateAstNode<FloatLiteral>(node);
Expand Down Expand Up @@ -1579,7 +1610,7 @@ private bool TryParseParameter(FlowScriptParser.ParameterContext context, out Pa
else
{
var sizeLiteral = context.arraySignifier().IntLiteral();
if (!(sizeLiteral != null && TryParseIntLiteral(sizeLiteral, out var size)))
if (!(sizeLiteral != null && TryParseUIntLiteral(sizeLiteral, out var size)))
{
LogError(context, "Array parameter must have array size specified");
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal class ProcedureInfo

public Procedure OriginalCompiled { get; set; }

public short Index { get; set; }
public ushort Index { get; set; }

public bool IndexForced { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,34 +149,34 @@ public bool TryDeclareFunction(FunctionDeclaration declaration)
return true;
}

public bool TryDeclareFunctions(FunctionDeclaration[] declarations)
public bool TryDeclareFunctions(FunctionDeclaration[] declarations)
{
foreach (var declaration in declarations)
{
foreach(var declaration in declarations)
{
if(!TryDeclareFunction(declaration))
return false;
}
return true;
if (!TryDeclareFunction(declaration))
return false;
}
return true;
}


public bool TryDeclareProcedure( ProcedureDeclaration declaration, out ProcedureInfo procedure )
public bool TryDeclareProcedure(ProcedureDeclaration declaration, out ProcedureInfo procedure)
{
if (TryGetProcedure(declaration.Identifier.Text, out procedure))
{
if ( TryGetProcedure( declaration.Identifier.Text, out procedure ) )
{
return false;
}
return false;
}

var p = new ProcedureInfo();
p.Declaration = declaration;
p.IndexForced = declaration.Index != null;
p.Index = !p.IndexForced ? (short)Procedures.Count : (short)declaration.Index.Value;
p.Index = !p.IndexForced ? (ushort)Procedures.Count : (ushort)declaration.Index.Value;
if (Procedures.Any(x => x.Value.Index == p.Index))
{
var duplicate = !p.IndexForced ? p : Procedures.Values.FirstOrDefault(x => x.Index == p.Index && !x.IndexForced);
if (duplicate == null)
duplicate = p; // If there's nothing else that can be replaced then this just can't have its index forced
short newIndex = 0;
ushort newIndex = 0;
while (Procedures.Any(x => x.Value.Index == newIndex))
newIndex++;
duplicate.Index = newIndex;
Expand All @@ -198,10 +198,10 @@ public bool TryDeclareProcedure(ProcedureDeclaration declaration, Procedure comp

public bool TryDeclareVariable(VariableDeclaration declaration)
{
return TryDeclareVariable(declaration, -1);
return TryDeclareVariable(declaration, ushort.MaxValue);
}

public bool TryDeclareVariable(VariableDeclaration declaration, short index, int size = 1)
public bool TryDeclareVariable(VariableDeclaration declaration, ushort index, int size = 1)
{
if (TryGetVariable(declaration.Identifier.Text, out _))
return false;
Expand All @@ -227,7 +227,7 @@ public bool TryDeclareEnum(EnumDeclaration declaration)
Members = declaration.Values.ToDictionary(x => x.Identifier.Text, y => y.Value)
};

int nextMemberValue = 0;
long nextMemberValue = 0;
bool anyImplicitValues = false;

for (int i = 0; i < enumType.Members.Count; i++)
Expand All @@ -237,7 +237,8 @@ public bool TryDeclareEnum(EnumDeclaration declaration)

if (value == null)
{
enumType.Members[key] = new IntLiteral(nextMemberValue++);
enumType.Members[key] = nextMemberValue < 0 ? new IntLiteral((int)nextMemberValue) : new UIntLiteral((uint)nextMemberValue);
nextMemberValue++;
anyImplicitValues = true;
}
else
Expand All @@ -256,9 +257,9 @@ public bool TryDeclareEnum(EnumDeclaration declaration)
return true;
}

private bool TryGetNextMemberValue(Dictionary<string, Expression> members, Expression enumValue, out int nextMemberValue)
private bool TryGetNextMemberValue(Dictionary<string, Expression> members, Expression enumValue, out long nextMemberValue)
{
if (enumValue is IntLiteral intLiteral)
if (enumValue is IIntLiteral intLiteral)
{
nextMemberValue = intLiteral.Value + 1;
return true;
Expand All @@ -276,7 +277,7 @@ private bool TryGetNextMemberValue(Dictionary<string, Expression> members, Expre
return false;
}

public VariableInfo GenerateVariable(ValueKind kind, short index)
public VariableInfo GenerateVariable(ValueKind kind, ushort index)
{
var declaration = new VariableDeclaration(
new VariableModifier(VariableModifierKind.Local),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ internal class VariableInfo
{
public VariableDeclaration Declaration { get; set; }

public short Index { get; set; }
public ushort Index { get; set; }

public int Size { get; set; } = 1;

public short GetArrayElementIndex(int index)
public ushort GetArrayElementIndex(int index)
{
if (Declaration.Modifier.Kind != VariableModifierKind.Global)
return (short)(Index + index);
return (ushort)(Index + index);
else
return (short)(Index - index);
return (ushort)(Index - index);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public override void Visit(FunctionDeclaration functionDeclaration)
{
Write("function");
WriteOpenParenthesis();
WriteHexIntegerLiteral((int)functionDeclaration.Index.Value);
WriteHexIntegerLiteral((uint)functionDeclaration.Index.Value);
WriteCloseParenthesis();
Write(" ");
Visit(functionDeclaration.ReturnType);
Expand All @@ -219,7 +219,7 @@ public override void Visit(VariableDeclaration variableDeclaration)
if (variableDeclaration.Modifier.Index != null)
{
WriteOpenParenthesis();
WriteIntegerLiteral(variableDeclaration.Modifier.Index);
WriteUnsignedIntegerLiteral(variableDeclaration.Modifier.Index);
WriteCloseParenthesis();
}

Expand Down Expand Up @@ -569,6 +569,11 @@ public override void Visit(IntLiteral literal)
WriteIntegerLiteral(literal);
}

public override void Visit(UIntLiteral literal)
{
WriteUnsignedIntegerLiteral(literal);
}

public override void Visit(StringLiteral literal)
{
WriteStringLiteral(literal);
Expand Down Expand Up @@ -740,7 +745,7 @@ private void WriteParameters(List<Parameter> parameters)

// Literals
// Integer literal
private void WriteIntegerLiteral(IntLiteral intLiteral)
private void WriteUnsignedIntegerLiteral(UIntLiteral intLiteral)
{
if (IsPowerOfTwo(intLiteral.Value) && (intLiteral.Value & 0xF) == 0)
{
Expand All @@ -752,7 +757,19 @@ private void WriteIntegerLiteral(IntLiteral intLiteral)
}
}

private void WriteHexIntegerLiteral(int value)
private void WriteIntegerLiteral(IntLiteral intLiteral)
{
if (intLiteral.Value >= 0 && IsPowerOfTwo((uint)intLiteral.Value) && (intLiteral.Value & 0xF) == 0)
{
WriteHexIntegerLiteral((uint)intLiteral.Value);
}
else
{
Write(intLiteral.Value.ToString());
}
}

private void WriteHexIntegerLiteral(uint value)
{
if (FitsInByte(value))
Write($"0x{value:X2}");
Expand All @@ -762,17 +779,17 @@ private void WriteHexIntegerLiteral(int value)
Write($"0x{value:X8}");
}

private bool IsPowerOfTwo(int x)
private bool IsPowerOfTwo(uint x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}

private bool FitsInShort(int value)
private bool FitsInShort(uint value)
{
return (((value & 0xffff8000) + 0x8000) & 0xffff7fff) == 0;
}

private bool FitsInByte(int value)
private bool FitsInByte(uint value)
{
// doesn't catch negative values but that doesn't matter in this context
return (value & ~0xFF) == 0;
Expand Down
Loading

0 comments on commit d6c62d2

Please sign in to comment.