From 8972a277f3f4b718667e457755cbed16f93c59b9 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 16 Dec 2022 18:04:57 +0200 Subject: [PATCH] Data - Added new type `VariableParameter` for function parameters Parser - Generate instances of `VariableParameter` instead of just `Variable` (direct) for function parameters - Set the Container of the VariableParameter(s) of a function definition to that of the Function (definition) TypeCheck - Updated type to `VariableParameter` (just to be more specific and clear) Dependency - Added branch to pool VariableParameter but NOT add them as dnode's (that would cause code gen to emit declarations for parameters - which is something we do not want). Set as visited, pool for lookup and set Context. DGen - Added variable parameter symbol mapping to `generateSignature()` for function signatures Variables (special DNode type) - Added note, do we need these? Test cases - Updated test case `simple_function_decls.t` to test parameter variable usage (assignment and expression usage) --- source/tlang/compiler/codegen/emit/dgen.d | 14 +++++-- source/tlang/compiler/parsing/core.d | 13 +++--- source/tlang/compiler/symbols/data.d | 40 ++++++++++++++++--- source/tlang/compiler/typecheck/core.d | 2 +- .../compiler/typecheck/dependency/core.d | 20 +++++++++- .../compiler/typecheck/dependency/variables.d | 2 + source/tlang/testing/simple_function_decls.t | 8 +++- 7 files changed, 81 insertions(+), 18 deletions(-) diff --git a/source/tlang/compiler/codegen/emit/dgen.d b/source/tlang/compiler/codegen/emit/dgen.d index b0f4f02..7bfad4a 100644 --- a/source/tlang/compiler/codegen/emit/dgen.d +++ b/source/tlang/compiler/codegen/emit/dgen.d @@ -14,7 +14,7 @@ import std.string : wrap; import std.process : spawnProcess, Pid, ProcessException, wait; import compiler.typecheck.dependency.core : Context, FunctionData, DNode; import compiler.codegen.mapper : SymbolMapper; -import compiler.symbols.data : SymbolType, Variable, Function; +import compiler.symbols.data : SymbolType, Variable, Function, VariableParameter; import compiler.symbols.check : getCharacter; import misc.utils : Stack; @@ -287,13 +287,21 @@ public final class DCodeEmitter : CodeEmitter // Generate parameter list if(func.hasParams()) { - Variable[] parameters = func.getParams(); + VariableParameter[] parameters = func.getParams(); string parameterString; for(ulong parIdx = 0; parIdx < parameters.length; parIdx++) { Variable currentParameter = parameters[parIdx]; - parameterString~=currentParameter.getType()~" "~currentParameter.getName(); + + // Generate the symbol-mapped names for the parameters + Variable typedEntityVariable = cast(Variable)typeChecker.getResolver().resolveBest(func, currentParameter.getName()); //TODO: Remove `auto` + string typedEntityVariableName = typeChecker.getResolver().generateName(func, typedEntityVariable); + string renamedSymbol = SymbolMapper.symbolLookup(func, typedEntityVariableName); + + + // Generate + parameterString~=currentParameter.getType()~" "~renamedSymbol; if(parIdx != (parameters.length-1)) { diff --git a/source/tlang/compiler/parsing/core.d b/source/tlang/compiler/parsing/core.d index 9833107..37e38b4 100644 --- a/source/tlang/compiler/parsing/core.d +++ b/source/tlang/compiler/parsing/core.d @@ -718,7 +718,7 @@ public final class Parser private struct funcDefPair { Statement[] bodyStatements; - Variable[] args; + VariableParameter[] params; } private funcDefPair parseFuncDef() @@ -726,7 +726,7 @@ public final class Parser gprintln("parseFuncDef(): Enter", DebugType.WARNING); Statement[] statements; - Variable[] argumentList; + VariableParameter[] parameterList; funcDefPair bruh; @@ -760,7 +760,7 @@ public final class Parser /* Add the local variable (parameter variable) */ - argumentList ~= new Variable(type, identifier); + parameterList ~= new VariableParameter(type, identifier); moreArgs = false; @@ -807,7 +807,7 @@ public final class Parser gprintln("parseFuncDef(): Leave", DebugType.WARNING); bruh.bodyStatements = statements; - bruh.args = argumentList; + bruh.params = parameterList; return bruh; } @@ -1146,12 +1146,15 @@ public final class Parser { funcDefPair pair = parseFuncDef(); - generated = new Function(identifier, type, pair.bodyStatements, pair.args); + generated = new Function(identifier, type, pair.bodyStatements, pair.params); import std.stdio; writeln(to!(string)((cast(Function)generated).getVariables())); + // Parent the parameters of the function to the Function + parentToContainer(cast(Container)generated, cast(Statement[])pair.params); + // Parent the statements that make up the function to the Function parentToContainer(cast(Container)generated, pair.bodyStatements); } /* Check for semi-colon (var dec) */ diff --git a/source/tlang/compiler/symbols/data.d b/source/tlang/compiler/symbols/data.d index 394ad49..1122e8a 100644 --- a/source/tlang/compiler/symbols/data.d +++ b/source/tlang/compiler/symbols/data.d @@ -231,24 +231,54 @@ public class ArgumentList } + +/** + * VariableParameter + * + * Represents a kindof-Variable which is used to indicate + * it is a function's parameter - to differentiate between + * those and other variables like local/global definitions + * and so on + * + * These are only to be used in the `Function` class (below) + */ +public final class VariableParameter : Variable +{ + this(string type, string identifier) + { + super(type, identifier); + } +} + /* TODO: Don't make this a Container, or maybe (make sure I don't rely on COntainer casting for other shit * though, also the recent changes) */ public class Function : TypedEntity, Container { - private Variable[] params; + private VariableParameter[] params; private Statement[] bodyStatements; - this(string name, string returnType, Statement[] bodyStatements, Variable[] args) + this(string name, string returnType, Statement[] bodyStatements, VariableParameter[] params) { super(name, returnType); - this.bodyStatements = bodyStatements; - this.params = args; + + // Add the parameters first THEN the function's body statements + // because they must be available before other statements + // which may reference them, Secondly they must be added (the VariableParameter(s)) + // such that they are lookup-able. + addStatements(cast(Statement[])params); + + // Add the funciton's body + addStatements(bodyStatements); + + // Save a seperate copy of the parameters (to seperate them from the + // other body stetements) + this.params = params; /* Weighted as 1 */ weight = 1; } - public Variable[] getParams() + public VariableParameter[] getParams() { return params; } diff --git a/source/tlang/compiler/typecheck/core.d b/source/tlang/compiler/typecheck/core.d index 54e9d1f..9cb40cc 100644 --- a/source/tlang/compiler/typecheck/core.d +++ b/source/tlang/compiler/typecheck/core.d @@ -632,7 +632,7 @@ public final class TypeChecker /* TODO: Look up func def to know when popping stops (types-based delimiting) */ Function func = cast(Function)resolver.resolveBest(modulle, funcCall.getName()); assert(func); - Variable[] paremeters = func.getParams(); + VariableParameter[] paremeters = func.getParams(); /* TODO: Pass in FUnction, so we get function's body for calling too */ diff --git a/source/tlang/compiler/typecheck/dependency/core.d b/source/tlang/compiler/typecheck/dependency/core.d index 905585f..fef1417 100644 --- a/source/tlang/compiler/typecheck/dependency/core.d +++ b/source/tlang/compiler/typecheck/dependency/core.d @@ -736,7 +736,6 @@ public class DNodeGenerator varExp.setContext(context); gprintln("Kont: "~to!(string)(context)); - if(namedEntity) { @@ -1179,10 +1178,27 @@ public class DNodeGenerator continue; } + /** + * Variable paremeters (for functions) + */ + if(cast(VariableParameter)entity) + { + VariableParameter varParamDec = cast(VariableParameter)entity; + + // Set context + entity.setContext(context); + + // Pool and mark as visited + // NOTE: I guess for now use VariableDNode as that is what is used in expressionPass + // with the poolT! constrcutor, doing otherwise causes a cast failure and hence + // null: /git/tlang/tlang/issues/52#issuecomment-325 + DNode dnode = poolT!(VariableNode, Variable)(varParamDec); + dnode.markVisited(); + } /** * Variable declarations */ - if(cast(Variable)entity) + else if(cast(Variable)entity) { /* Get the Variable and information */ Variable variable = cast(Variable)entity; diff --git a/source/tlang/compiler/typecheck/dependency/variables.d b/source/tlang/compiler/typecheck/dependency/variables.d index a2f9568..6a1bd46 100644 --- a/source/tlang/compiler/typecheck/dependency/variables.d +++ b/source/tlang/compiler/typecheck/dependency/variables.d @@ -9,6 +9,8 @@ import compiler.symbols.data; * and struct-level */ +//TODO: See how needed these REALLY are (see issue #55) + public class VariableNode : DNode { private Variable variable; diff --git a/source/tlang/testing/simple_function_decls.t b/source/tlang/testing/simple_function_decls.t index 3f78bdc..83a66ca 100644 --- a/source/tlang/testing/simple_function_decls.t +++ b/source/tlang/testing/simple_function_decls.t @@ -3,12 +3,16 @@ module simple_function_decls; int j = 21; int k = 22; -int apple(int j, int arg2) +int apple(int arg1, int arg2) { int h = 69; + + arg1=1+arg1; + + k=1; } -int banana(int j) +int banana(int arg1) { int h = 64;