Implement While
This commit is contained in:
parent
52198147e2
commit
f66013cf12
@ -132,11 +132,6 @@ namespace Parser.Binding
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoundWhileStatement BindWhileStatement(WhileStatementSyntaxNode node)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private BoundTryCatchStatement BindTryCatchStatement(TryCatchStatementSyntaxNode node)
|
private BoundTryCatchStatement BindTryCatchStatement(TryCatchStatementSyntaxNode node)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@ -290,6 +285,13 @@ namespace Parser.Binding
|
|||||||
return Identifier(node, ((IdentifierNameExpressionSyntaxNode)node).Name.Text);
|
return Identifier(node, ((IdentifierNameExpressionSyntaxNode)node).Name.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BoundWhileStatement BindWhileStatement(WhileStatementSyntaxNode node)
|
||||||
|
{
|
||||||
|
var condition = BindConversion(BindExpression(node.Condition), TypeSymbol.Boolean);
|
||||||
|
var body = BindStatement(node.Body);
|
||||||
|
return WhileStatement(node, condition, body);
|
||||||
|
}
|
||||||
|
|
||||||
private BoundExpressionStatement BindExpressionStatement(ExpressionStatementSyntaxNode node)
|
private BoundExpressionStatement BindExpressionStatement(ExpressionStatementSyntaxNode node)
|
||||||
{
|
{
|
||||||
var expression = BindExpression(node.Expression);
|
var expression = BindExpression(node.Expression);
|
||||||
|
@ -133,6 +133,14 @@ namespace Parser.Binding
|
|||||||
return new BoundGotoStatement(syntax, label);
|
return new BoundGotoStatement(syntax, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BoundWhileStatement WhileStatement(
|
||||||
|
SyntaxNode syntax,
|
||||||
|
BoundExpression condition,
|
||||||
|
BoundStatement body)
|
||||||
|
{
|
||||||
|
return new BoundWhileStatement(syntax, condition, body);
|
||||||
|
}
|
||||||
|
|
||||||
public static BoundIdentifierNameExpression Identifier(
|
public static BoundIdentifierNameExpression Identifier(
|
||||||
SyntaxNode syntax,
|
SyntaxNode syntax,
|
||||||
string name)
|
string name)
|
||||||
|
@ -256,12 +256,18 @@ namespace Parser.Binding
|
|||||||
|
|
||||||
public class BoundWhileStatement : BoundStatement
|
public class BoundWhileStatement : BoundStatement
|
||||||
{
|
{
|
||||||
public BoundWhileStatement(SyntaxNode syntax)
|
public BoundWhileStatement(SyntaxNode syntax, BoundExpression condition, BoundStatement body)
|
||||||
: base(syntax)
|
: base(syntax)
|
||||||
{
|
{
|
||||||
|
Condition = condition;
|
||||||
|
Body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BoundNodeKind Kind => BoundNodeKind.WhileStatement;
|
public override BoundNodeKind Kind => BoundNodeKind.WhileStatement;
|
||||||
|
|
||||||
|
public BoundExpression Condition { get; }
|
||||||
|
|
||||||
|
public BoundStatement Body { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class BoundExpression : BoundNode
|
public abstract class BoundExpression : BoundNode
|
||||||
|
@ -70,7 +70,9 @@ namespace Parser.Binding
|
|||||||
|
|
||||||
public virtual BoundStatement RewriteWhileStatement(BoundWhileStatement node)
|
public virtual BoundStatement RewriteWhileStatement(BoundWhileStatement node)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var condition = RewriteExpression(node.Condition);
|
||||||
|
var body = RewriteStatement(node.Body);
|
||||||
|
return WhileStatement(node.Syntax, condition, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual BoundStatement RewriteTryCatchStatement(BoundTryCatchStatement node)
|
public virtual BoundStatement RewriteTryCatchStatement(BoundTryCatchStatement node)
|
||||||
|
@ -28,6 +28,11 @@
|
|||||||
return Implicit;
|
return Implicit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (to == TypeSymbol.Boolean)
|
||||||
|
{
|
||||||
|
return Implicit;
|
||||||
|
}
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -467,8 +467,13 @@ namespace Parser.Emitting
|
|||||||
|
|
||||||
private void EmitConditionalGoto(BoundConditionalGotoStatement node, ILProcessor ilProcessor)
|
private void EmitConditionalGoto(BoundConditionalGotoStatement node, ILProcessor ilProcessor)
|
||||||
{
|
{
|
||||||
EmitExpression(node.Condition, ilProcessor);
|
var condition = ConvertExpression(node.Condition, TypeSymbol.Boolean);
|
||||||
ilProcessor.Emit(OpCodes.Call, _mObjectToBool);
|
if (condition is null)
|
||||||
|
{
|
||||||
|
throw new Exception("Cannot cast a condition in GOTO to boolean.");
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitExpression(condition, ilProcessor);
|
||||||
var instruction = node.GotoIfTrue ? OpCodes.Brtrue : OpCodes.Brfalse;
|
var instruction = node.GotoIfTrue ? OpCodes.Brtrue : OpCodes.Brfalse;
|
||||||
if (_labels.TryGetValue(node.Label, out var target))
|
if (_labels.TryGetValue(node.Label, out var target))
|
||||||
{
|
{
|
||||||
@ -569,7 +574,7 @@ namespace Parser.Emitting
|
|||||||
{
|
{
|
||||||
ilProcessor.Emit(OpCodes.Call, _doubleToMObject);
|
ilProcessor.Emit(OpCodes.Call, _doubleToMObject);
|
||||||
}
|
}
|
||||||
if ((fromType, toType) == (TypeSymbol.Int, TypeSymbol.MObject))
|
else if ((fromType, toType) == (TypeSymbol.Int, TypeSymbol.MObject))
|
||||||
{
|
{
|
||||||
ilProcessor.Emit(OpCodes.Call, _intToMObject);
|
ilProcessor.Emit(OpCodes.Call, _intToMObject);
|
||||||
}
|
}
|
||||||
@ -577,6 +582,10 @@ namespace Parser.Emitting
|
|||||||
{
|
{
|
||||||
ilProcessor.Emit(OpCodes.Call, _stringToMObject);
|
ilProcessor.Emit(OpCodes.Call, _stringToMObject);
|
||||||
}
|
}
|
||||||
|
else if ((fromType, toType) == (TypeSymbol.MObject, TypeSymbol.Boolean))
|
||||||
|
{
|
||||||
|
ilProcessor.Emit(OpCodes.Call, _mObjectToBool);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new NotImplementedException($"Conversion of '{fromType}' to '{toType}' is not implemented.");
|
throw new NotImplementedException($"Conversion of '{fromType}' to '{toType}' is not implemented.");
|
||||||
|
@ -86,6 +86,41 @@ namespace Parser.Lowering
|
|||||||
return RewriteBlockStatement(Block(node.Syntax, builder.ToArray()));
|
return RewriteBlockStatement(Block(node.Syntax, builder.ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override BoundStatement RewriteWhileStatement(BoundWhileStatement node)
|
||||||
|
{
|
||||||
|
// while cond
|
||||||
|
// body
|
||||||
|
// end
|
||||||
|
//
|
||||||
|
// |
|
||||||
|
// |
|
||||||
|
// V
|
||||||
|
//
|
||||||
|
// LabelLoop:
|
||||||
|
// gotoFalse cond LabelEnd
|
||||||
|
// body
|
||||||
|
// goto LabelLoop
|
||||||
|
// LabelEnd:
|
||||||
|
var labelLoop = GenerateLabel();
|
||||||
|
var labelEnd = GenerateLabel();
|
||||||
|
var result = Block(
|
||||||
|
node.Syntax,
|
||||||
|
// LabelLoop:
|
||||||
|
LabelStatement(node.Syntax, labelLoop),
|
||||||
|
// gotoFalse cond LabelEnd
|
||||||
|
GotoIfFalse(
|
||||||
|
node.Syntax,
|
||||||
|
node.Condition,
|
||||||
|
labelEnd),
|
||||||
|
// body
|
||||||
|
node.Body,
|
||||||
|
// goto LabelLoop
|
||||||
|
Goto(node.Syntax, labelLoop),
|
||||||
|
// LabelEnd:
|
||||||
|
LabelStatement(node.Syntax, labelEnd));
|
||||||
|
return RewriteBlockStatement(result);
|
||||||
|
}
|
||||||
|
|
||||||
public override BoundStatement RewriteForStatement(BoundForStatement node)
|
public override BoundStatement RewriteForStatement(BoundForStatement node)
|
||||||
{
|
{
|
||||||
// for i = expr
|
// for i = expr
|
||||||
@ -102,7 +137,6 @@ namespace Parser.Lowering
|
|||||||
// #index = #index + 1
|
// #index = #index + 1
|
||||||
// goto LabelLoop
|
// goto LabelLoop
|
||||||
// LabelEnd:
|
// LabelEnd:
|
||||||
var builder = ImmutableArray.CreateBuilder<BoundStatement>();
|
|
||||||
var labelLoop = GenerateLabel();
|
var labelLoop = GenerateLabel();
|
||||||
var labelEnd = GenerateLabel();
|
var labelEnd = GenerateLabel();
|
||||||
var localArray = GenerateTypedLocalVariable(TypeSymbol.MObject);
|
var localArray = GenerateTypedLocalVariable(TypeSymbol.MObject);
|
||||||
|
@ -5,6 +5,12 @@ f(x);
|
|||||||
x = 3;
|
x = 3;
|
||||||
f(x);
|
f(x);
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
while i <= 10
|
||||||
|
disp(i);
|
||||||
|
i = i + 1;
|
||||||
|
end
|
||||||
|
|
||||||
% for i = 1:10
|
% for i = 1:10
|
||||||
% disp(i);
|
% disp(i);
|
||||||
% end
|
% end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user