Skip to content

Commit

Permalink
Merge pull request #54 from Kisioj/ikarus-and-lego-support
Browse files Browse the repository at this point in the history
Ikarus and lego support + some bug fixes + new tests added
  • Loading branch information
arturkasperek committed Jul 7, 2019
2 parents 5d351a5 + 1366c1b commit e42885e
Show file tree
Hide file tree
Showing 18 changed files with 736 additions and 251 deletions.
10 changes: 10 additions & 0 deletions docs/changelog/changes-v0.6.1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h2>Changelog</h2>
<h3>Features</h3>
<ul>
<li>Added full support of Ikarus & Lego (newest versions)</li>
<li>Added new warning when the only code in the line is single expression</li>
<li>Added strict mode that turns warnings into errors</li>
<li>Added //suppress: WARNING_CODE comments to suppress warnings</li>
<li>Added new error detection, when there is too big integer value</li>
<li>Fixed few minor bugs</li>
</ul>
17 changes: 10 additions & 7 deletions src/DaedalusCompiler/Compilation/AssemblyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public AssemblyBuilderSnapshot(AssemblyBuilder assemblyBuilder)
AssignmentType = assemblyBuilder.AssignmentType;
FuncCallCtx = assemblyBuilder.FuncCallCtx == null ? null : new FuncCallContext(assemblyBuilder.FuncCallCtx);

ErrorContext = new ErrorContext(assemblyBuilder.ErrorContext);;
ErrorContext = new ErrorContext(assemblyBuilder.ErrorContext);
}
}

Expand Down Expand Up @@ -56,10 +56,11 @@ public class AssemblyBuilder
public DatSymbolType AssignmentType;
private int _nextSymbolIndex;
private bool _verbose;
public bool StrictSyntax;

public readonly List<CompilationMessage> Errors;

public AssemblyBuilder(bool verbose = true)
public AssemblyBuilder(bool verbose = true, bool strictSyntax=false)
{
ExecBlocks = new List<BaseExecBlockContext>();
Symbols = new List<DatSymbol>();
Expand All @@ -80,7 +81,8 @@ public AssemblyBuilder(bool verbose = true)
AssignmentType = DatSymbolType.Undefined;
_nextSymbolIndex = 0;
_verbose = verbose;

StrictSyntax = strictSyntax;

Errors = new List<CompilationMessage>();
ErrorContext = new ErrorContext(this);
}
Expand Down Expand Up @@ -400,12 +402,13 @@ public void AssignmentEnd(string assignmentOperator)

public void ExitOperator(string operatorText, bool twoArg=true)
{
var instruction = AssemblyBuilderHelpers.GetInstructionForOperator(operatorText, twoArg);
_activeContext.SetEndInstruction(instruction);
if (!IsInsideConstDef)
{
var instruction = AssemblyBuilderHelpers.GetInstructionForOperator(operatorText, twoArg);
_activeContext.SetEndInstruction(instruction);
}
}



public void FuncCallStart(string funcName)
{
DatSymbol symbol = GetSymbolByName(funcName);
Expand Down
58 changes: 52 additions & 6 deletions src/DaedalusCompiler/Compilation/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Antlr4.Runtime.Tree;
using DaedalusCompiler.Dat;

Expand All @@ -17,13 +18,27 @@ public class Compiler
private readonly string _outputDirPath;


public Compiler(string outputDirPath="output", bool verbose=true)
public Compiler(string outputDirPath="output", bool verbose=true, bool strictSyntax=false)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
_assemblyBuilder = new AssemblyBuilder(verbose);
_assemblyBuilder = new AssemblyBuilder(verbose, strictSyntax);
_ouBuilder = new OutputUnitsBuilder(verbose);
_outputDirPath = outputDirPath;
}

public static string[] GetWarningCodesToSuppress(string line)
{
string ws = @"(?:[ \t])*";
string newline = @"(?:\r\n?|\n)";
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline;
string suppressWarningsPattern = $@"//{ws}suppress{ws}:((?:{ws}[a-zA-Z0-9]+)+){ws}{newline}?$";
MatchCollection matches = Regex.Matches(line, suppressWarningsPattern, options);
foreach (Match match in matches)
{
return match.Groups[1].Value.Split(" ").Where(s => !s.Equals(String.Empty)).ToArray();
}
return new string[]{};
}

public string GetBuiltinsPath()
{
Expand Down Expand Up @@ -66,6 +81,9 @@ public string GetBuiltinsPath()
_assemblyBuilder.ErrorContext.FileContentLines = fileContent.Split(Environment.NewLine);
_assemblyBuilder.ErrorContext.FilePath = paths[i];
_assemblyBuilder.ErrorContext.FileIndex = i;
_assemblyBuilder.ErrorContext.SuppressedWarningCodes = Compiler.GetWarningCodesToSuppress(
_assemblyBuilder.ErrorContext.FileContentLines[0]
);
ParseTreeWalker.Default.Walk(new DaedalusListener(_assemblyBuilder, i), parser.daedalusFile());
if (generateOutputUnits)
{
Expand All @@ -84,15 +102,39 @@ public string GetBuiltinsPath()
}

_assemblyBuilder.Finish();
if (_assemblyBuilder.Errors.Any())

List<CompilationMessage> errors = new List<CompilationMessage>();
foreach (CompilationMessage error in _assemblyBuilder.Errors)
{
if (error is CompilationError)
{
errors.Add(error);
}
else if (error is CompilationWarning compilationWarning)
{
if (compilationWarning.IsSuppressed == false)
{
errors.Add(compilationWarning);
}
}
}

if (errors.Any())
{
_assemblyBuilder.Errors.Sort((x, y) => x.CompareTo(y));
errors.Sort((x, y) => x.CompareTo(y));

bool stopCompilation = _assemblyBuilder.StrictSyntax;

string lastErrorFilePath = "";
string lastErrorBlockName = null;
var logger = new StdErrorLogger();
foreach (CompilationMessage error in _assemblyBuilder.Errors)
foreach (CompilationMessage error in errors)
{
if (error is CompilationError)
{
stopCompilation = true;
}

if (lastErrorFilePath != error.FilePath)
{
lastErrorFilePath = error.FilePath;
Expand All @@ -115,7 +157,11 @@ public string GetBuiltinsPath()

error.Print(logger);
}
return false;

if (stopCompilation)
{
return false;
}
}

if (compileToAssembly)
Expand Down
49 changes: 47 additions & 2 deletions src/DaedalusCompiler/Compilation/DaedalusListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ public override void EnterConstDef([NotNull] DaedalusParser.ConstDefContext cont
}

var location = GetLocation(context);
var assignmentExpression = constValueContext.constValueAssignment().expressionBlock().expression();
DaedalusParser.ExpressionContext assignmentExpression = constValueContext.constValueAssignment().expressionBlock().expression();

_assemblyBuilder.ErrorContext.Context = assignmentExpression;
var value = EvaluatorHelper.EvaluateConst(assignmentExpression, _assemblyBuilder, type);

var symbol = SymbolBuilder.BuildConst(name, type, value, location); // TODO : Validate params
Expand All @@ -141,6 +143,13 @@ public override void EnterConstDef([NotNull] DaedalusParser.ConstDefContext cont
_assemblyBuilder.ErrorContext.Context = constArrayContext;

var name = constArrayContext.nameNode().GetText();
if (_assemblyBuilder.IsContextInsideExecBlock())
{
BaseExecBlockContext baseExecBlock = _assemblyBuilder.ExecBlocks.Last();
string execBlockName = baseExecBlock.GetSymbol().Name;
name = $"{execBlockName}.{name}";
}

var location = GetLocation(context);

int declaredSize = 0;
Expand Down Expand Up @@ -245,6 +254,13 @@ public override void EnterVarDecl([NotNull] DaedalusParser.VarDeclContext contex
if (varContext is DaedalusParser.VarArrayDeclContext varArrayContext)
{
var name = varArrayContext.nameNode().GetText();
if (_assemblyBuilder.IsContextInsideExecBlock())
{
BaseExecBlockContext baseExecBlock = _assemblyBuilder.ExecBlocks.Last();
string execBlockName = baseExecBlock.GetSymbol().Name;
name = $"{execBlockName}.{name}";
}

var location = GetLocation(context);
var size = EvaluatorHelper.EvaluteArraySize(varArrayContext.arraySize(), _assemblyBuilder);

Expand Down Expand Up @@ -380,6 +396,13 @@ public override void EnterInstanceDecl(DaedalusParser.InstanceDeclContext contex
DatSymbol instanceSymbol = SymbolBuilder.BuildInstance(instanceName, referenceSymbolId, location);
_assemblyBuilder.AddSymbol(instanceSymbol);
symbols.Add(instanceSymbol);

if (refSymbol.Type == DatSymbolType.Prototype)
{
_assemblyBuilder.ExecBlockStart(instanceSymbol, ExecBlockType.Instance);
_assemblyBuilder.AddInstruction(new Call(refSymbol));
_assemblyBuilder.ExecBlockEnd();
}
}

_assemblyBuilder.SharedBlockStart(symbols);
Expand Down Expand Up @@ -564,6 +587,16 @@ public override void EnterIntegerLiteralValue(DaedalusParser.IntegerLiteralValue
{
if (!_assemblyBuilder.IsInsideConstDef)
{
RuleContext grandparentContext = context.Parent.Parent;
if (grandparentContext is DaedalusParser.OneArgExpressionContext oneArgExpressionContext)
{
_assemblyBuilder.ErrorContext.Context = oneArgExpressionContext;
}
else
{
_assemblyBuilder.ErrorContext.Context = context;
}

bool isInsideFloatAssignment = _assemblyBuilder.IsInsideAssignment
&& _assemblyBuilder.AssignmentType == DatSymbolType.Float;
bool isInsideFloatArgument = _assemblyBuilder.IsInsideArgList
Expand All @@ -576,7 +609,8 @@ public override void EnterIntegerLiteralValue(DaedalusParser.IntegerLiteralValue
}
else
{
_assemblyBuilder.AddInstruction(new PushInt(int.Parse(context.GetText())));
int parsedInt = EvaluatorHelper.IntParse(context.GetText(), _assemblyBuilder);
_assemblyBuilder.AddInstruction(new PushInt(parsedInt));
}
}
}
Expand Down Expand Up @@ -605,6 +639,17 @@ public override void EnterStringLiteralValue(DaedalusParser.StringLiteralValueCo
/*
* ENTER EXPRESSION
*/
public override void EnterExpressionBlock(DaedalusParser.ExpressionBlockContext context)
{
_assemblyBuilder.ErrorContext.Context = context;
if (context.Parent is DaedalusParser.StatementContext)
{
_assemblyBuilder.Errors.Add(
new SingleExpressionWarning(_assemblyBuilder.ErrorContext, _assemblyBuilder.StrictSyntax)
);
}
}

public override void EnterBracketExpression(DaedalusParser.BracketExpressionContext context)
{
_assemblyBuilder.ExpressionStart();
Expand Down
11 changes: 9 additions & 2 deletions src/DaedalusCompiler/Compilation/DatBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,19 @@ public DatFile GetDatFile()
{
foreach (var symbol in sharedBlock.Symbols)
{
symbol.FirstTokenAddress = _currentAddress;
if (symbol.FirstTokenAddress == -1)
{
symbol.FirstTokenAddress = _currentAddress;
}
}
}
else
{
execBlock.GetSymbol().FirstTokenAddress = _currentAddress;
DatSymbol symbol = execBlock.GetSymbol();
if (symbol.FirstTokenAddress == -1)
{
symbol.FirstTokenAddress = _currentAddress;
}
}
tokens.AddRange(GetTokens(execBlock));
}
Expand Down
23 changes: 14 additions & 9 deletions src/DaedalusCompiler/Compilation/EvaluatorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ private static float GetFloat(string value)
$"Unable to evaluate constant. Expression '{value}' contains unsupported operations.");
}
}

public static int IntParse(string text, AssemblyBuilder assemblyBuilder)
{
try
{
return int.Parse(text);
}
catch (OverflowException)
{
assemblyBuilder.Errors.Add(new IntegerLiteralTooLargeError(assemblyBuilder.ErrorContext));
return 0;
}
}

private static int EvaluateConstIntExpression(DaedalusParser.ExpressionContext expression,
AssemblyBuilder assemblyBuilder, string oper="")
Expand Down Expand Up @@ -120,15 +133,7 @@ private static float GetFloat(string value)
// value is simple literal
if (valueChild is TerminalNodeImpl)
{
try
{
return int.Parse(valueText);
}
catch (OverflowException)
{
// TODO should throw error for too small/ big int
throw new OverflowException();
}
return IntParse(valueText, assemblyBuilder);
}

// value is reference to other constant
Expand Down
Loading

0 comments on commit e42885e

Please sign in to comment.