Skip to content

Commit

Permalink
support for Throwable and Iterable interface
Browse files Browse the repository at this point in the history
  • Loading branch information
burdoto committed Mar 6, 2022
1 parent dee3c84 commit 059e509
Show file tree
Hide file tree
Showing 18 changed files with 129 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Compile System Package.run.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Compile System Package" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="$PROJECT_DIR$/kscr-runtime/bin/Debug/net5.0/kscr.exe" />
<option name="PROGRAM_PARAMETERS" value="compile --system true --sources kscr-system/ --output kscr-runtime/bin/Debug/net5.0/std/" />
<option name="PROGRAM_PARAMETERS" value="compile --system --sources kscr-system/core/Throwable.kscr kscr-system/core/Iterator.kscr kscr-system/core/Iterable.kscr --output kscr-runtime/bin/Debug/net5.0/std/" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
Expand Down
2 changes: 1 addition & 1 deletion Test Execute.run.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test Execute" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="$PROJECT_DIR$/kscr-runtime/bin/Debug/net5.0/kscr.exe" />
<option name="PROGRAM_PARAMETERS" value="execute --debug --sources kscr-system/core/Throwable.kscr examples/PrintNumbers.kscr --output examples/build/compile/" />
<option name="PROGRAM_PARAMETERS" value="execute --debug --sources examples/PrintNumbers.kscr --output examples/build/compile/" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
Expand Down
5 changes: 3 additions & 2 deletions examples/PrintNumbers.kscr
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.comroid.kscr.test;

import org.comroid.kscr.core.Throwable;
import org.comroid.kscr.core.Iterable;

public class PrintNumbers implements Throwable {
public static int StackSize -> 64;
Expand All @@ -12,10 +13,10 @@ public class PrintNumbers implements Throwable {

// prints numbers 0 to 11
public static void main() {
void range = 0~12; // todo: range as non-compile-time constant
Iterable range = 0~12; // todo: range as non-compile-time constant

stdio << "print numbers " + range.start() + " to (exclusive) " + (range.end() - 1 + 1) + ":";
forn (i : range)
foreach (i : range)
stdio << i;

stdio << "and now backwards bcs we're cool:";
Expand Down
6 changes: 3 additions & 3 deletions kscr-compiler/Class/ClassCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private void ResetData()
while (ctx.NextToken?.Type == TokenType.Word)
{
ctx.TokenIndex += 1;
var cls = ctx.FindFullTypeInfo(vm) as IClassInstance;
var cls = ctx.FindTypeInfo(vm) as IClassInstance;
if (cls == null)
throw new CompilerException(ctx.Token.SourcefilePosition,
"Invalid extends-Token; Type not found");
Expand All @@ -120,7 +120,7 @@ private void ResetData()
while (ctx.NextToken?.Type == TokenType.Word)
{
ctx.TokenIndex += 1;
var cls = ctx.FindFullTypeInfo(vm) as IClassInstance;
var cls = ctx.FindTypeInfo(vm) as IClassInstance;
if (cls == null)
throw new CompilerException(ctx.Token.SourcefilePosition,
"Invalid implements-Token; Type not found: " + ctx.NextToken?.Arg!);
Expand All @@ -138,7 +138,7 @@ private void ResetData()
if (targetType == null)
{
// is return type
targetType = ctx.FindFullTypeInfo(vm);
targetType = ctx.FindTypeInfo(vm);
}
else if (memberName == null)
// is name
Expand Down
6 changes: 5 additions & 1 deletion kscr-compiler/Class/TypeParameterDefinitionCompiler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using KScr.Lib;
using System.Linq;
using KScr.Lib;
using KScr.Lib.Bytecode;
using KScr.Lib.Exception;
using KScr.Lib.Model;
Expand Down Expand Up @@ -29,6 +30,9 @@ public TypeParameterDefinitionCompiler(ClassCompiler parent, IClass @class) : ba
if (pIndex >= _class.BaseClass.TypeParameters.Count)
throw new CompilerException(ctx.Token.SourcefilePosition, "Invalid TypeParameter index during compilation");

var context = ctx;
if (_class.TypeParameters.Any(x => x.Name == context.Token.Arg!))
break;
_class.TypeParameters.Add(new TypeParameter(ctx.Token.Arg!));
pIndex += 1;
pState += 1;
Expand Down
2 changes: 1 addition & 1 deletion kscr-compiler/Code/CodeCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ protected AbstractCodeCompiler(ICompiler parent) : base(parent)
{
if (ctx.NextToken?.Type == TokenType.Word)
{ // declaration
CompileDeclaration(ctx,type);
CompileDeclaration(ctx, type);
}
else
{ // type expression
Expand Down
10 changes: 4 additions & 6 deletions kscr-compiler/Code/StatementCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,18 @@ public StatementCompiler(ICompiler parent, bool endBeforeTerminator = false, par
ctx.LastComponent!.InnerCode = subctx.ExecutableCode;
ctx.TokenIndex = subctx.TokenIndex;
return this;
case TokenType.ForN:
case TokenType.ForEach:
if (ctx.NextToken?.Type != TokenType.ParRoundOpen)
throw new CompilerException(ctx.Token.SourcefilePosition, "Invalid forn-Statement; missing specification");
ctx.Statement = new Statement
{
Type = StatementComponentType.Code,
CodeType = BytecodeType.StmtForN
CodeType = BytecodeType.StmtForEach
};
ctx.Component = new StatementComponent
{
Type = StatementComponentType.Code,
CodeType = BytecodeType.StmtForN,
CodeType = BytecodeType.StmtForEach,
SourcefilePosition = ctx.Token.SourcefilePosition
};

Expand All @@ -216,7 +216,7 @@ public StatementCompiler(ICompiler parent, bool endBeforeTerminator = false, par
{
Type = StatementComponentType.Code,
CodeType = BytecodeType.Expression,
TargetType = Lib.Bytecode.Class.RangeType.DefaultInstance
TargetType = Lib.Bytecode.Class.IterableType.DefaultInstance
};
CompilerLoop(vm, new ExpressionCompiler(this, false, TokenType.ParRoundClose), ref subctx);
ctx.LastComponent!.SubStatement = subctx.Statement;
Expand All @@ -230,8 +230,6 @@ public StatementCompiler(ICompiler parent, bool endBeforeTerminator = false, par
ctx.LastComponent!.InnerCode = subctx.ExecutableCode;
ctx.TokenIndex = subctx.TokenIndex;
return this;
case TokenType.ForEach:
throw new NotImplementedException("ForEach");
case TokenType.ParAccClose:
_active = false;
return this;
Expand Down
5 changes: 1 addition & 4 deletions kscr-compiler/Tokenizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,10 @@ private void LexicalToken(bool isWhitespace, ref string str, char c,
token = new Token(srcPos, TokenType.While);
return;
case "for":
if (n is 'n' or 'e')
if (n is 'e')
break;
token = new Token(srcPos, TokenType.For);
return;
case "forn":
token = new Token(srcPos, TokenType.ForN);
return;
case "foreach":
token = new Token(srcPos, TokenType.ForEach);
return;
Expand Down
45 changes: 43 additions & 2 deletions kscr-lib/Bytecode/Class.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public sealed class Class : AbstractPackageMember, IClass, IRuntimeSite
public static readonly Class StringType = new(LibClassPackage, "str", true, MemberModifier.Public | MemberModifier.Final);
public static readonly Class RangeType = new(LibClassPackage, "range", true, MemberModifier.Public | MemberModifier.Final);
public static readonly Class NumericType = new(LibClassPackage, "num", true, MemberModifier.Public | MemberModifier.Final) { TypeParameters = { new TypeParameter("T") } };
public static readonly Class IteratorType = new(LibClassPackage, "Iterator", true, MemberModifier.Public, ClassType.Interface) { TypeParameters = { new TypeParameter("T") } };
public static readonly Class IterableType = new(LibClassPackage, "Iterable", true, MemberModifier.Public, ClassType.Interface) { TypeParameters = { new TypeParameter("T") } };
public static readonly Class ThrowableType = new(LibClassPackage, "Throwable", true, MemberModifier.Public, ClassType.Interface);
public static readonly Instance NumericByteType = new(NumericType, (ITypeInfo)
new Class(LibClassPackage, "byte", true, MemberModifier.Public | MemberModifier.Final));
Expand Down Expand Up @@ -93,7 +95,7 @@ public Instance CreateInstance(RuntimeBase vm, Class? owner = null, params IType

public Class BaseClass => this;
public List<ITypeInfo> TypeParameters { get; } = new();
public TypeParameter.Instance[] TypeParameterInstances { get; } = Array.Empty<TypeParameter.Instance>();
public TypeParameter.Instance[] TypeParameterInstances { get; private set; } = Array.Empty<TypeParameter.Instance>();

public override string Name => base.Name +
(TypeParameters.Count == 0
Expand Down Expand Up @@ -357,7 +359,7 @@ public bool CanHold(IClass? type)
}
}

public static void InitializePrimitives(RuntimeBase runtimeBase)
public static void InitializePrimitives(RuntimeBase vm)
{
#region Void Class

Expand Down Expand Up @@ -449,6 +451,10 @@ public static void InitializePrimitives(RuntimeBase runtimeBase)
}
});
var decremental = new DummyMethod(VoidType, "decremental", MemberModifier.Public | MemberModifier.Final, NumericByteType);

// iterable methods
var iterator = new DummyMethod(IterableType, "iterator", MemberModifier.Public | MemberModifier.Abstract,
IteratorType.CreateInstance(vm, IterableType, IterableType.TypeParameters[0]));

AddToClass(RangeType, toString);
AddToClass(RangeType, equals);
Expand All @@ -458,6 +464,32 @@ public static void InitializePrimitives(RuntimeBase runtimeBase)
AddToClass(RangeType, accumulate);
AddToClass(RangeType, decremental);
AddToClass(RangeType, getType);
AddToClass(RangeType, iterator);
RangeType.Interfaces.Add(IterableType.CreateInstance(vm, RangeType, NumericIntType));

#endregion

#region Iterator Class

var current = new DummyMethod(IteratorType, "current", MemberModifier.Public | MemberModifier.Abstract, IteratorType.TypeParameters[0]);
var next = new DummyMethod(IteratorType, "next", MemberModifier.Public | MemberModifier.Abstract, IteratorType.TypeParameters[0]);
var hasNext = new DummyMethod(IteratorType, "hasNext", MemberModifier.Public | MemberModifier.Abstract, NumericByteType);

AddToClass(IteratorType, toString);
AddToClass(IteratorType, equals);
AddToClass(IteratorType, getType);
AddToClass(IteratorType, current);
AddToClass(IteratorType, next);
AddToClass(IteratorType, hasNext);

#endregion

#region Iterable Class

AddToClass(IterableType, toString);
AddToClass(IterableType, equals);
AddToClass(IterableType, getType);
AddToClass(IterableType, iterator);

#endregion

Expand Down Expand Up @@ -543,6 +575,15 @@ public Instance(TypeParameter typeParameter, ITypeInfo targetType)
public string Name => TypeParameter.Name;
public string FullName => TypeParameter.FullName;
public List<ITypeInfo> TypeParameters { get; } = new();

public IClassInstance ResolveType(RuntimeBase vm, IClassInstance usingClass)
{
if (usingClass.TypeParameterInstances.Length == 0
|| usingClass.TypeParameterInstances.All(x => x.TypeParameter.Name != TypeParameter.Name))
throw new ArgumentException("Invalid resolver class");
return vm.FindType(usingClass.TypeParameterInstances
.First(x => x.TypeParameter.Name == TypeParameter.Name).TargetType.FullName)!;
}
}
}
}
10 changes: 7 additions & 3 deletions kscr-lib/Bytecode/Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ public override void Write(Stream stream)
stream.Write(BitConverter.GetBytes(Parameters.Count));
foreach (var parameter in Parameters)
parameter.Write(stream);
Body.Write(stream);
if (!this.IsAbstract())
Body.Write(stream);
}

public override void Load(RuntimeBase vm, byte[] data, ref int i)
Expand All @@ -129,8 +130,11 @@ public override void Load(RuntimeBase vm, byte[] data, ref int i)
Parameters.Clear();
for (; len > 0; len--)
Parameters.Add(MethodParameter.Read(vm, data, ref i));
Body = new ExecutableCode();
Body.Load(vm, data, ref i);
if (!this.IsAbstract())
{
Body = new ExecutableCode();
Body.Load(vm, data, ref i);
}
}

public new static Method Read(RuntimeBase vm, Class parent, byte[] data, ref int i)
Expand Down
8 changes: 6 additions & 2 deletions kscr-lib/Bytecode/Package.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ public void Write(DirectoryInfo dir, ClassInfo[]? names = null)
{
names ??= Array.Empty<ClassInfo>();
foreach (var member in Members.Values)
if (!names.Any(name => name.FullName.StartsWith(member.FullName)))
if (!names.Any(name => name.FullName.StartsWith(member.FullName.Contains("<")
? member.FullName.Substring(0, member.FullName.IndexOf('<'))
: member.FullName)))
// ReSharper disable once RedundantJumpStatement
continue;
else if (member is Package pkg)
pkg.Write(dir.CreateSubdirectory(member.Name), names);
else if (member is Class cls)
cls.Write(new FileInfo(Path.Combine(dir.FullName, member.Name + ".kbin")));
cls.Write(new FileInfo(Path.Combine(dir.FullName, (member.Name.Contains("<")
? member.Name.Substring(0, member.Name.IndexOf("<", StringComparison.Ordinal))
: member.Name) + ".kbin")));
else throw new NotSupportedException("Member is of unsupported type: " + member.GetType());
}

Expand Down
18 changes: 10 additions & 8 deletions kscr-lib/Bytecode/Statement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,20 +248,22 @@ public virtual State Evaluate(RuntimeBase vm, ref ObjectRef rev)
return _rev;
});
break;
case (StatementComponentType.Code, BytecodeType.StmtForN):
vm.Stack.StepInside(vm, SourcefilePosition, "forn", ref rev, _rev =>
case (StatementComponentType.Code, BytecodeType.StmtForEach):
vm.Stack.StepInside(vm, SourcefilePosition, "foreach", ref rev, _rev =>
{
state = SubStatement!.Evaluate(vm, ref buf!);
if (state != State.Normal)
return _rev;
var range = (buf.Value as Range)!;
var n = vm[VariableContext.Local, Arg] = new ObjectRef(Class.NumericIntType);
n.Value = range.start(vm).Value;
do
var iterable = (buf.Value as IObject)!;
var iter = iterable.Invoke(vm, "iterator", ref buf!);
var iterator = iter.Value;
var n = vm[VariableContext.Local, Arg] = new ObjectRef(iterator.Type.TypeParameterInstances[0].ResolveType(vm, iterator.Type));
while (state == State.Normal && iterator.Invoke(vm, "hasNext", ref n).ToBool())
{
n.Value = iterator.Invoke(vm, "next", ref iter).Value;
iter.Value = iterator;
state = InnerCode!.Evaluate(vm, ref _rev);
n.Value = range.accumulate(vm, (n.Value as Numeric)!).Value;
} while (state == State.Normal && range.test(vm, (n.Value as Numeric)!).ToBool());
}
vm[VariableContext.Local, Arg] = null;
return _rev;
Expand Down
38 changes: 37 additions & 1 deletion kscr-lib/Core/Range.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ private Range(RuntimeBase vm, int start, int end)
return Start == other.Start && End == other.End ? vm.ConstantTrue : vm.ConstantFalse;
case "getType":
return Type.SelfRef;
case "iterator":
return vm.PutObject(VariableContext.Local, "iterator", new RangeIterator(vm, this));
case "start": // get first value
return start(vm);
case "end": // get last value
Expand All @@ -61,7 +63,41 @@ private Range(RuntimeBase vm, int start, int end)

throw new NotImplementedException();
}


private class RangeIterator : IObject
{
private readonly Range _range;
private ObjectRef? _n;

public RangeIterator(RuntimeBase vm, Range range)
{
_range = range;
ObjectId = vm.NextObjId(ToString(0));
Type = Class.IteratorType.CreateInstance(vm, Class.NumericIntType);
}

public long ObjectId { get; }
public IClassInstance Type { get; }

public string ToString(short variant) => "range-iterator:" + _range;

public ObjectRef? Invoke(RuntimeBase vm, string member, ref ObjectRef? rev, params IObject?[] args)
{
switch (member)
{
case "current":
return _n ?? vm.ConstantVoid;
case "next":
return _n = _n == null ? _range.start(vm) : _range.accumulate(vm, (_n.Value as Numeric)!);
case "hasNext":
return _n == null ? vm.ConstantTrue
: _range.test(vm, (_range.accumulate(vm, (_n.Value as Numeric)!).Value as Numeric)!);
default:
throw new InvalidOperationException();
}
}
}

public ObjectRef start(RuntimeBase vm) => Numeric.Constant(vm, Start);
public ObjectRef end(RuntimeBase vm) => Numeric.Constant(vm, End);
public ObjectRef test(RuntimeBase vm, Numeric n) => (Decremental ? n.IntValue > End : n.IntValue < End) ? vm.ConstantTrue : vm.ConstantFalse;
Expand Down
3 changes: 1 addition & 2 deletions kscr-lib/Model/BytecodePacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public enum BytecodeType : uint
StmtDo = 0x0021_0000 | Statement,
StmtWhile = 0x0022_0000 | Statement,
StmtFor = 0x0041_0000 | Statement,
StmtForN = 0x0042_0000 | Statement,
StmtForEach = 0x0044_0000 | Statement,
StmtForEach = 0x00422_0000 | Statement,

StdioExpression = 0x0200_0000,
ParameterExpression = 0x0100_0000,
Expand Down
Loading

0 comments on commit 059e509

Please sign in to comment.