Parser
- Added `allowVarDec` and `allwFuncDef` to `parseTypedDeclaration()` as default arguments with `true` as their default values - If `allowFuncDef` is true then parse a function - If `allowVarDec` is `true` then allow a variable definition - If `allowVarDec` is true but we have an assignment and `wantsBody` is false then throw an error - NOTE: A fix for `parseTypedDeclaration()` is needed for this to work Tests - Updated `simple_extern.t` to include an `extern evar`
This commit is contained in:
parent
aa11af5bba
commit
d288440e18
|
@ -1304,7 +1304,7 @@ public final class Parser
|
||||||
return retExpression[0];
|
return retExpression[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypedEntity parseTypedDeclaration(bool wantsBody = true)
|
private TypedEntity parseTypedDeclaration(bool wantsBody = true, bool allowVarDec = true, bool allowFuncDef = true)
|
||||||
{
|
{
|
||||||
gprintln("parseTypedDeclaration(): Enter", DebugType.WARNING);
|
gprintln("parseTypedDeclaration(): Enter", DebugType.WARNING);
|
||||||
|
|
||||||
|
@ -1346,55 +1346,89 @@ public final class Parser
|
||||||
gprintln("ParseTypedDec: SymbolType=" ~ to!(string)(symbolType));
|
gprintln("ParseTypedDec: SymbolType=" ~ to!(string)(symbolType));
|
||||||
if (symbolType == SymbolType.LBRACE)
|
if (symbolType == SymbolType.LBRACE)
|
||||||
{
|
{
|
||||||
funcDefPair pair = parseFuncDef(wantsBody);
|
// Only continue is function definitions are allowed
|
||||||
|
if(allowFuncDef)
|
||||||
|
{
|
||||||
|
funcDefPair pair = parseFuncDef(wantsBody);
|
||||||
|
|
||||||
generated = new Function(identifier, type, pair.bodyStatements, pair.params);
|
generated = new Function(identifier, type, pair.bodyStatements, pair.params);
|
||||||
|
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
writeln(to!(string)((cast(Function)generated).getVariables()));
|
writeln(to!(string)((cast(Function)generated).getVariables()));
|
||||||
|
|
||||||
// Parent the parameters of the function to the Function
|
// Parent the parameters of the function to the Function
|
||||||
parentToContainer(cast(Container)generated, cast(Statement[])pair.params);
|
parentToContainer(cast(Container)generated, cast(Statement[])pair.params);
|
||||||
|
|
||||||
// Parent the statements that make up the function to the Function
|
// Parent the statements that make up the function to the Function
|
||||||
parentToContainer(cast(Container)generated, pair.bodyStatements);
|
parentToContainer(cast(Container)generated, pair.bodyStatements);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expect("Function definitions not allowed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Check for semi-colon (var dec) */
|
/* Check for semi-colon (var dec) */
|
||||||
else if (symbolType == SymbolType.SEMICOLON)
|
else if (symbolType == SymbolType.SEMICOLON)
|
||||||
{
|
{
|
||||||
nextToken();
|
// Only continue if variable declarations are allowed
|
||||||
gprintln("ParseTypedDec: VariableDeclaration: (Type: " ~ type ~ ", Identifier: " ~ identifier ~ ")",
|
if(allowVarDec)
|
||||||
DebugType.WARNING);
|
{
|
||||||
|
gprintln("Semi: "~to!(string)(getCurrentToken()));
|
||||||
|
nextToken();
|
||||||
|
gprintln("Semi: "~to!(string)(getCurrentToken()));
|
||||||
|
gprintln("ParseTypedDec: VariableDeclaration: (Type: " ~ type ~ ", Identifier: " ~ identifier ~ ")",
|
||||||
|
DebugType.WARNING);
|
||||||
|
|
||||||
generated = new Variable(type, identifier);
|
generated = new Variable(type, identifier);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expect("Variables declarations are not allowed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Check for `=` (var dec) */
|
/* Check for `=` (var dec) */
|
||||||
else if (symbolType == SymbolType.ASSIGN)
|
else if (symbolType == SymbolType.ASSIGN)
|
||||||
{
|
{
|
||||||
nextToken();
|
// Only continue if variable declarations are allowed
|
||||||
|
if(allowVarDec)
|
||||||
|
{
|
||||||
|
// Only continue if assignments are allowed
|
||||||
|
if(wantsBody)
|
||||||
|
{
|
||||||
|
nextToken();
|
||||||
|
|
||||||
/* Now parse an expression */
|
/* Now parse an expression */
|
||||||
Expression expression = parseExpression();
|
Expression expression = parseExpression();
|
||||||
|
|
||||||
VariableAssignment varAssign = new VariableAssignment(expression);
|
VariableAssignment varAssign = new VariableAssignment(expression);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The symbol that returned us from `parseExpression` must
|
* The symbol that returned us from `parseExpression` must
|
||||||
* be a semi-colon
|
* be a semi-colon
|
||||||
*/
|
*/
|
||||||
expect(SymbolType.SEMICOLON, getCurrentToken());
|
expect(SymbolType.SEMICOLON, getCurrentToken());
|
||||||
|
|
||||||
nextToken();
|
nextToken();
|
||||||
|
|
||||||
gprintln("ParseTypedDec: VariableDeclarationWithAssingment: (Type: "
|
gprintln("ParseTypedDec: VariableDeclarationWithAssingment: (Type: "
|
||||||
~ type ~ ", Identifier: " ~ identifier ~ ")", DebugType.WARNING);
|
~ type ~ ", Identifier: " ~ identifier ~ ")", DebugType.WARNING);
|
||||||
|
|
||||||
Variable variable = new Variable(type, identifier);
|
Variable variable = new Variable(type, identifier);
|
||||||
variable.addAssignment(varAssign);
|
variable.addAssignment(varAssign);
|
||||||
|
|
||||||
varAssign.setVariable(variable);
|
varAssign.setVariable(variable);
|
||||||
|
|
||||||
generated = variable;
|
generated = variable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expect("Variable assignments+declarations are not allowed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expect("Variables declarations are not allowed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1796,14 +1830,16 @@ public final class Parser
|
||||||
{
|
{
|
||||||
// TODO: (For one below)(we should also disallow somehow assignment) - evar
|
// TODO: (For one below)(we should also disallow somehow assignment) - evar
|
||||||
|
|
||||||
// We now parse function definition but with wantsBody false
|
// We now parse function definition but with `wantsBody` set to false
|
||||||
pseudoEntity = parseTypedDeclaration(false);
|
// indicating no body should be allowed.
|
||||||
|
pseudoEntity = parseTypedDeclaration(false, false, true);
|
||||||
}
|
}
|
||||||
/* External variable symbol */
|
/* External variable symbol */
|
||||||
else if(externType == SymbolType.EXTERN_EVAR)
|
else if(externType == SymbolType.EXTERN_EVAR)
|
||||||
{
|
{
|
||||||
// TODO: Implement me
|
// We now parse a variable declaration but with the `wantsBody` set to false
|
||||||
assert(false);
|
// indicating no assignment should be allowed.
|
||||||
|
pseudoEntity = parseTypedDeclaration(false, true, false);
|
||||||
}
|
}
|
||||||
/* Anything else is invalid */
|
/* Anything else is invalid */
|
||||||
else
|
else
|
||||||
|
@ -1811,6 +1847,11 @@ public final class Parser
|
||||||
expect("Expected either extern function (efunc) or extern variable (evar)");
|
expect("Expected either extern function (efunc) or extern variable (evar)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: If we are doing all this semi-colon stuff in `parseTypedDecaration()` then we ought
|
||||||
|
// ... to put the below code in there. Compare body ending `}` and nextToken()'ing it
|
||||||
|
// ... to a vardec finishing on `;` and then returning to `parseName()` which does nothing
|
||||||
|
// ... we could seem how we go about this, perhaps body is the exception case, and we should
|
||||||
|
// ... be nextToken()'ing and before that exoecting in `parseName()` and here, `parseExtern()'
|
||||||
/* Expect a semicolon to end it all and then consume it */
|
/* Expect a semicolon to end it all and then consume it */
|
||||||
expect(SymbolType.SEMICOLON, getCurrentToken());
|
expect(SymbolType.SEMICOLON, getCurrentToken());
|
||||||
nextToken();
|
nextToken();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module simple_extern;
|
module simple_extern;
|
||||||
|
|
||||||
extern efunc uint write(uint fd, ubyte* buffer, uint count);
|
extern efunc uint write(uint fd, ubyte* buffer, uint count);
|
||||||
|
extern evar int stdin;
|
||||||
|
|
||||||
void test()
|
void test()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue