Skip to content

Commit

Permalink
Predicat type added
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomast2001 committed Apr 16, 2024
1 parent 72b730f commit c99dc58
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 23 deletions.
3 changes: 2 additions & 1 deletion SctBuildTasks/Sct.g4
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ agent_predicate:
FUNCTION: 'function';
RIGHT_ARROW: '->';

type: T_INT | T_FLOAT | T_VOID;
type: T_INT | T_FLOAT | T_VOID | T_PREDICATE;
T_INT: 'int';
T_FLOAT: 'float';
T_VOID: 'void';
T_PREDICATE: 'Predicate';

ASSIGN: '=';
IF: 'if';
Expand Down
23 changes: 9 additions & 14 deletions SocietalConstructionTool/Compiler/TypeTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;

using Sct.Compiler.Exceptions;
using Sct.Runtime;

namespace Sct.Compiler
{
Expand All @@ -17,30 +18,24 @@ public static class TypeTable
{ "int", new SctType(typeof(int), "int") },
{ "float", new SctType(typeof(double), "float") },
{ "void", new SctType(typeof(void), "void")},
{ "Predicate", new SctType(typeof(void), "Predicate") },
{ "Predicate", new SctType(typeof(QueryPredicate), "Predicate") },
{ "none", new SctType(typeof(void), "none")}
};

public static SctType? GetType(string name) => Types[name];

public static TypeSyntax GetTypeNode(string name)
{
SctType sctType = (Types[name]) ?? throw new InvalidTypeException($"Type {name} does not exist");
if (sctType == Types["Predicate"])
if (Types[name] is null) throw new InvalidTypeException($"Type {name} does not exist");
static PredefinedTypeSyntax PredefinedType(SyntaxKind kind) => SyntaxFactory.PredefinedType(SyntaxFactory.Token(kind));
var @type = name switch
{
throw new InvalidTypeException("Predicate type cannot be used as a syntax node");
}

var syntaxKind = name switch
{
"int" => SyntaxKind.LongKeyword,
"float" => SyntaxKind.DoubleKeyword,
"void" => SyntaxKind.VoidKeyword,
_ => throw new InvalidTypeException($"Got unknown type in translation: ${name}")
"int" => PredefinedType(SyntaxKind.LongKeyword),
"float" => PredefinedType(SyntaxKind.DoubleKeyword),
"void" => PredefinedType(SyntaxKind.VoidKeyword),
_ => SyntaxFactory.ParseTypeName(Types[name].TargetType.Name)
};

var @type = SyntaxFactory.PredefinedType(SyntaxFactory.Token(syntaxKind));

return @type;
}

Expand Down
20 changes: 12 additions & 8 deletions SocietalConstructionTool/Compiler/Typechecker/SctTypeChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ public override SctType VisitVariableDeclaration([NotNull] SctParser.VariableDec
{
var type = context.type().Accept(this);

// TODO: Maybe add predicate later :)
if (type == TypeTable.Predicate || type == TypeTable.Void)
if (type == TypeTable.Void)
{
_errors.Add(new CompilerError($"Variable cannot be of type: {type.TypeName}", context.Start.Line, context.Start.Column));
}
Expand Down Expand Up @@ -94,12 +93,6 @@ public override SctType VisitClass_def([NotNull] SctParser.Class_defContext cont
// can never be null, as SctTableVisitor created the class
_currentClass = _ctable.GetClassContent(context.ID().GetText())!;
_vtable.EnterScope();

foreach (var (id, type) in context.args_def().ID().Zip(context.args_def().type()))
{
_ = _vtable.AddEntry(id.GetText(), type.Accept(this));
}

_ = base.VisitClass_def(context);
_currentClass = _ctable.GlobalClass;
_vtable.ExitScope();
Expand Down Expand Up @@ -139,10 +132,21 @@ public override SctType VisitFunction([NotNull] SctParser.FunctionContext contex
{
return TypeTable.Void;
}
_vtable.EnterScope();
_ = context.args_def().Accept(this);
_ = context.type().Accept(this);
_ = context.statement_list()?.Accept(this); // function may not have a body
_vtable.ExitScope();
return TypeTable.None;
}

public override SctType VisitArgs_def([NotNull] SctParser.Args_defContext context)
{
// return base.VisitArgs_def(context);
foreach (var (id, type) in context.ID().Zip(context.type()))
{
_ = _vtable.AddEntry(id.GetText(), type.Accept(this));
}
return TypeTable.None;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(start (class_def class Citizen ( (args_def (type int) townId) ) { (class_body (state state Child { (statement_list (statement (enter enter Adult ;))) }) (state state Adult { (statement_list (statement (enter enter Adult ;))) })) }) (function function duplicate ( (args_def (type Predicate) p) ) -> (type int) { (statement_list (statement (if if ( (expression (expression (call_expression count ( (args_call (expression p)) ))) > (expression (literal 1))) ) { (statement_list (statement (return return (expression (literal 1)) ;))) })) (statement (return return (expression (literal 0)) ;))) }) (function function Setup ( args_def ) -> (type void) { (statement_list (statement (declaration (type Predicate) x = (expression (agent_predicate Citizen :: Child ( (args_agent townId : (expression (literal 1))) ))) ;)) (statement (if if ( (expression (call_expression duplicate ( (args_call (expression x)) ))) ) { (statement_list (statement (exit exit ( ) ;))) }))) }) <EOF>)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(start (class_def class Citizen ( (args_def (type int) townId) ) { (class_body (state state Child { (statement_list (statement (enter enter Adult ;))) }) (state state Adult { (statement_list (statement (enter enter Adult ;))) })) }) (function function getChildPredicate ( (args_def (type int) id) ) -> (type Predicate) { (statement_list (statement (return return (expression (agent_predicate Citizen :: Child ( (args_agent townId : (expression id)) ))) ;))) }) (function function Setup ( args_def ) -> (type void) { (statement_list (statement (declaration (type int) townId = (expression (literal 5)) ;)) (statement (declaration (type int) childrenCount = (expression (call_expression count ( (args_call (expression (call_expression getChildPredicate ( (args_call (expression townId)) )))) ))) ;))) }) <EOF>)
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
namespace SctGenerated
{
using Sct.Runtime;
using System;
using System.Collections.Generic;

public class GlobalClass
{
public static void __sct_Setup(IRuntimeContext ctx)
{
QueryPredicate __sct_x = new QueryPredicate("__sct_Citizen", "__sct_Child", new Dictionary<String, dynamic>(new KeyValuePair<String, dynamic>[] { new KeyValuePair<String, dynamic>("__sct_townId", 1) }));
if (__sct_duplicate(ctx, __sct_x) != 0)
{
ctx.ExitRuntime();
return true;
}
}

public static long __sct_duplicate(IRuntimeContext ctx, Predicate __sct_p)
{
if (((ctx.QueryHandler.Count(ctx, __sct_p) > 1) ? 1 : 0) != 0)
{
return 1;
}

return 0;
}

public class __sct_Citizen : BaseAgent
{
private int __sct_townId { get => Fields["__sct_townId"]; set => Fields["__sct_townId"] = value; }

public __sct_Citizen(String state, IDictionary<String, dynamic> fields) : base(state, fields)
{
}

private bool __sct_Child(IRuntimeContext ctx)
{
Enter(ctx, "__sct_Adult");
return true;
return false;
}

private bool __sct_Adult(IRuntimeContext ctx)
{
Enter(ctx, "__sct_Adult");
return true;
return false;
}

public override void Update(IRuntimeContext ctx)
{
_ = State switch
{
"__sct_Child" => __sct_Child(ctx),
"__sct_Adult" => __sct_Adult(ctx)};
}
}

public static void RunSimulation(IRuntimeContext ctx)
{
Runtime runtime = new Runtime();
__sct_Setup(ctx);
runtime.Run(ctx);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace SctGenerated
{
using Sct.Runtime;
using System;
using System.Collections.Generic;

public class GlobalClass
{
public static void __sct_Setup(IRuntimeContext ctx)
{
long __sct_townId = 5;
long __sct_childrenCount = ctx.QueryHandler.Count(ctx, __sct_getChildPredicate(ctx, __sct_townId));
}

public static QueryPredicate __sct_getChildPredicate(IRuntimeContext ctx, int __sct_id)
{
return new QueryPredicate("__sct_Citizen", "__sct_Child", new Dictionary<String, dynamic>(new KeyValuePair<String, dynamic>[] { new KeyValuePair<String, dynamic>("__sct_townId", __sct_id) }));
}

public class __sct_Citizen : BaseAgent
{
private int __sct_townId { get => Fields["__sct_townId"]; set => Fields["__sct_townId"] = value; }

public __sct_Citizen(String state, IDictionary<String, dynamic> fields) : base(state, fields)
{
}

private bool __sct_Child(IRuntimeContext ctx)
{
Enter(ctx, "__sct_Adult");
return true;
return false;
}

private bool __sct_Adult(IRuntimeContext ctx)
{
Enter(ctx, "__sct_Adult");
return true;
return false;
}

public override void Update(IRuntimeContext ctx)
{
_ = State switch
{
"__sct_Child" => __sct_Child(ctx),
"__sct_Adult" => __sct_Adult(ctx)};
}
}

public static void RunSimulation(IRuntimeContext ctx)
{
Runtime runtime = new Runtime();
__sct_Setup(ctx);
runtime.Run(ctx);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
emptyString
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Citizen(int townId) {
state Child {
enter Adult;
}

state Adult {
enter Adult;
}
}

function duplicate(Predicate p) -> int{
if (count(p) > 1) {
return 1;
}
return 0;
}

function Setup() -> void {
Predicate x = Citizen::Child(townId:1);
if (duplicate(x)) {
exit();
}
}
18 changes: 18 additions & 0 deletions SocietalConstructionToolTests/TestFiles/Parser/ReturnPredicate.sct
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Citizen(int townId) {
state Child {
enter Adult;
}

state Adult {
enter Adult;
}
}

function getChildPredicate(int id) -> Predicate {
return Citizen::Child(townId: id);
}

function Setup() -> void {
int townId = 5;
int childrenCount = count(getChildPredicate(townId));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Foo(int a, int b) {
state Bar {
enter Bar;
}
}

function Setup() -> void {
Predicate x = Foo::Bar(a:5);
if(exists(x)){
int y = 5;
}
}

0 comments on commit c99dc58

Please sign in to comment.