Skip to content

Commit

Permalink
Merge 0cec777 into ce32cfe
Browse files Browse the repository at this point in the history
  • Loading branch information
deavmi committed May 9, 2024
2 parents ce32cfe + 0cec777 commit f517e59
Show file tree
Hide file tree
Showing 10 changed files with 429 additions and 5 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/d.yml
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,23 @@ jobs:
exit 1
fi
- name: Alias expression test that returns 3
run: |
set -e
./tlang compile source/tlang/testing/simple_aliases.t
set +e
./tlang.out
if [ $? = 3 ]
then
set -e
exit 0
else
set -e
exit 1
fi
##################################
Expand Down
3 changes: 2 additions & 1 deletion source/tlang/compiler/core.d
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,8 @@ unittest
"source/tlang/testing/universal_coerce/simple_coerce_literal_good.t",
"source/tlang/testing/universal_coerce/simple_coerce_literal_good_stdalo.t",
"source/tlang/testing/simple_function_return_type_check_good.t",
"source/tlang/testing/modules/a.t"
"source/tlang/testing/modules/a.t",
"source/tlang/testing/simple_aliases.t"
];

foreach(string testFileGood; testFilesGood)
Expand Down
48 changes: 48 additions & 0 deletions source/tlang/compiler/parsing/core.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import tlang.compiler.parsing.exceptions;
import tlang.compiler.core : Compiler;
import std.string : format;
import tlang.compiler.modman;
import tlang.compiler.symbols.aliases;

// TODO: Technically we could make a core parser etc
public final class Parser
Expand Down Expand Up @@ -2324,6 +2325,43 @@ public final class Parser
}
}

/**
* Parses an alias declaration
*
* Returns: an `AliasDeclaration`
*/
private AliasDeclaration parseAliasDeclaration()
{
WARN("parseAliasDeclaration(): Enter");

AliasDeclaration aliasDecl;

/* Pop off the `alias` */
lexer.nextToken();

/* Consume the alias's name */
Token tok = lexer.getCurrentToken();
expect(SymbolType.IDENT_TYPE, tok);
string aliasName = tok.getToken();

/* Next token, expect `=` */
lexer.nextToken();
expect(SymbolType.ASSIGN, lexer.getCurrentToken());

/* Now consume an expression */
lexer.nextToken();
Expression aliasExpr = parseExpression();
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();

/* Construct an alias with the name and expression */
aliasDecl = new AliasDeclaration(aliasName, aliasExpr);

WARN("parseAliasDeclaration(): Leave");

return aliasDecl;
}

// TODO: We need to add `parseComment()`
// support here (see issue #84)
// TODO: This ic currently dead code and ought to be used/implemented
Expand Down Expand Up @@ -2405,6 +2443,11 @@ public final class Parser
ERROR("COMMENTS NOT YET PROPERLY SUPOORTED");
parseComment();
}
/* If it is an alias declaration */
else if(symbol == SymbolType.ALIAS)
{
statement = parseAliasDeclaration();
}
/* Error out */
else
{
Expand Down Expand Up @@ -2794,6 +2837,11 @@ public final class Parser
ERROR("COMMENTS NOT YET PROPERLY SUPOORTED");
parseComment();
}
/* If it is an alias declaration */
else if(symbol == SymbolType.ALIAS)
{
modulle.addStatement(parseAliasDeclaration());
}
else
{
expect("parse(): Unknown '" ~ tok.getToken() ~ "'");
Expand Down
35 changes: 35 additions & 0 deletions source/tlang/compiler/symbols/aliases.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module tlang.compiler.symbols.aliases;

import tlang.compiler.symbols.data : Statement;
import tlang.compiler.symbols.expressions : Expression;
import std.string : format;

/**
* A declaration of an alias expression
*/
public final class AliasDeclaration : Statement
{
private string aliasName;
private Expression aliasExpr;

this(string aliasName, Expression aliasExpr)
{
this.aliasName = aliasName;
this.aliasExpr = aliasExpr;
}

public string getName()
{
return this.aliasName;
}

public Expression getExpr()
{
return this.aliasExpr;
}

public override string toString()
{
return format("Alias [name: %s]", this.aliasName);
}
}
11 changes: 11 additions & 0 deletions source/tlang/compiler/symbols/check.d
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@ public enum SymbolType
*/
SINGLE_LINE_COMMENT,

/**
* `alias` keyword
*/
ALIAS,

/**
* Unknown symbol
*/
Expand Down Expand Up @@ -715,6 +720,11 @@ public SymbolType getSymbolType(Token tokenIn)
{
return SymbolType.IMPORT;
}
/* `alias` keyword */
else if(cmp("alias", token) == 0)
{
return SymbolType.ALIAS;
}
/* An identifier/type (of some sorts) - further inspection in parser is needed */
else if(isPathIdentifier(token) || isIdentifier(token))
{
Expand Down Expand Up @@ -841,6 +851,7 @@ public SymbolType getSymbolType(Token tokenIn)
return SymbolType.SMALLER_THAN_OR_EQUALS;
}



return SymbolType.UNKNOWN;
}
Expand Down
74 changes: 70 additions & 4 deletions source/tlang/compiler/symbols/data.d
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,42 @@ public final class Program : Container

public bool replace(Statement thiz, Statement that)
{
// TODO: Implement me
return false;
/* We cannot replace ourselves */
if(thiz == this)
{
return false;
}
/* If not ourselves, then search our body */
else
{
/* Check for module replacement */
for(size_t i = 0; i < this.modules.length; i++)
{
Module mod = this.modules[i];

/* If we are replacing a module */
if(thiz == mod)
{
this.modules[i] = cast(Module)that;
that.parentTo(this);
return true;
}
}

/* Check for replacement WITHIN each module */
for(size_t i = 0; i < this.modules.length; i++)
{
Module mod = this.modules[i];

/* If we are replacing WITHIN a module */
if(mod.replace(thiz, that))
{
return true;
}
}

return false;
}
}

public void addStatement(Statement statement)
Expand Down Expand Up @@ -1016,7 +1050,7 @@ public class Call : IdentExpression
}

// FIXME: Finish adding proper `MStatementSearchable` and `MStatementReplaceable` to `FunctionCall`
public final class FunctionCall : Call, MStatementSearchable, MStatementReplaceable
public final class FunctionCall : Call, MStatementSearchable, MStatementReplaceable, MCloneable
{
/* Whether this is statement-level function call or not */

Expand Down Expand Up @@ -1117,7 +1151,39 @@ public final class FunctionCall : Call, MStatementSearchable, MStatementReplacea
// {
// return false;
// }
return true;
return false;
}

/**
* Clones this integer literal
*
* Param:
* newParent = the `Container` to re-parent the
* cloned `Statement`'s self to
*
* Returns: the cloned `Statement`
*/
public override Statement clone(Container newParent = null)
{
// Clone arguments
Expression[] clonedArgs;
foreach(Expression arg; clonedArgs)
{
MCloneable argClonable = cast(MCloneable)arg;
if(argClonable)
{
clonedArgs ~= cast(Expression)argClonable.clone();
}
}

FunctionCall clonedFuncCall = new FunctionCall(this.name, clonedArgs);

DEBUG("haram");

// Parent outselves to the given parent
clonedFuncCall.parentTo(newParent);

return clonedFuncCall;
}
}

Expand Down
104 changes: 104 additions & 0 deletions source/tlang/compiler/symbols/mcro.d
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,108 @@ public interface MCloneable
* Returns: the cloned `Statement`
*/
public Statement clone(Container newParent = null);
}

/**
* Any AST type which implements this
* then will provide the ability to
* compare the AST nodes within itself
* (what that means is up to the implementing
* node)
*/
public interface MComparable
{
/**
* Compares the two nodes and reports
* on the position of `thiz` relative
* to `that`.
*
* Params:
* thiz = the first AST node
* that = the second AST node
* Returns: a `Pos`
*/
public Pos compare(Statement thiz, Statement that);

/**
* Compares the two statements and returns
* a value depending on which AST node
* precedes the other.
*
* Params:
* thiz = the first AST node
* that = the second AST node
* Returns: `true` if `thiz` comes before
* `that`, `false` otherwise
*/
public final bool isBefore(Statement thiz, Statement that)
{
return compare(thiz, that) == Pos.BEFORE;
}

/**
* Compares the two statements and returns
* a value depending on which AST node
* proceeds the other.
*
* Params:
* thiz = the first AST node
* that = the second AST node
* Returns: `true` if `thiz` comes after
* `that`, `false` otherwise
*/
public final bool isAfter(Statement thiz, Statement that)
{
return compare(thiz, that) == Pos.AFTER;
}

public enum Pos
{
/**
* If the position is the
* first node coming before
* the other
*/
BEFORE,

/**
* If the position is the
* first node coming after
* the other
*/
AFTER,

/**
* If both nodes are infact
* the same node
*/
SAME,

/**
* To be returned on an error
* dependant on implementation
*/
ERROR
}

}

/**
* Defines an interface for determining
* the position of an AST node nested
* within the implementing one
*/
public interface MPositionable
{
/**
* Determines the position of the
* given AST node within this
* node
*
* Params:
* statement = the statement
* Returns: the position or -1
* if invalid
*/
public size_t position(Statement statement);
}

0 comments on commit f517e59

Please sign in to comment.