added macrodef
This commit is contained in:
@@ -108,6 +108,7 @@ type
|
||||
function VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
|
||||
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
|
||||
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
|
||||
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
||||
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
|
||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
||||
@@ -359,6 +360,20 @@ begin
|
||||
raise Exception.Create('Syntax Error: Expected an identifier for def statement.');
|
||||
Result := TAst.VarDecl(IIdentifierNode(tailNodes[0]), IfThen(Length(tailNodes) > 1, tailNodes[1], nil));
|
||||
end
|
||||
else if SameText(head.Token.Text, 'defmacro') then
|
||||
begin
|
||||
// (defmacro name [params] body)
|
||||
if (Length(tailNodes) <> 3) or (tailTokens[0].Kind <> tkIdentifier) then
|
||||
raise Exception.Create('Syntax Error: ''defmacro'' requires a name, a parameter list, and a body.');
|
||||
if elements[1].Node <> nil then
|
||||
raise Exception.Create('Syntax Error: Expected a parameter list [...] after macro name.');
|
||||
|
||||
var macroName := IIdentifierNode(tailNodes[0]);
|
||||
var macroParams := elements[1].Params;
|
||||
var macroBody := tailNodes[2];
|
||||
|
||||
Result := TAst.MacroDef(macroName, macroParams, macroBody);
|
||||
end
|
||||
else if SameText(head.Token.Text, 'assign') then
|
||||
begin
|
||||
if tailTokens[0].Kind <> tkIdentifier then
|
||||
@@ -424,6 +439,19 @@ var
|
||||
i64: Int64;
|
||||
dbl: Double;
|
||||
begin
|
||||
// TODO: Implement reader macros for quasiquoting here.
|
||||
// The current lexer will tokenize `, ~, and ~@ as identifiers.
|
||||
// Check for them here and wrap the subsequent expression accordingly.
|
||||
// Example:
|
||||
// if FCurrentToken.Text = '`' then
|
||||
// begin
|
||||
// NextToken;
|
||||
// var exprToQuote := ParseExpression;
|
||||
// Result.Node := TAst.Quasiquote(exprToQuote.Node);
|
||||
// exit;
|
||||
// end;
|
||||
// (This requires IQuasiquoteNode and TAst.Quasiquote to be defined first).
|
||||
|
||||
Result.Token := FCurrentToken;
|
||||
case FCurrentToken.Kind of
|
||||
tkNumber:
|
||||
@@ -606,6 +634,33 @@ begin
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
||||
var
|
||||
param: IIdentifierNode;
|
||||
sb: TStringBuilder;
|
||||
begin
|
||||
// Added visitor for pretty printing macro definitions.
|
||||
sb := TStringBuilder.Create;
|
||||
try
|
||||
for param in Node.Parameters do
|
||||
sb.Append(param.Name + ' ');
|
||||
if sb.Length > 0 then
|
||||
sb.Remove(sb.Length - 1, 1);
|
||||
|
||||
Append('(defmacro ' + Node.Name.Name + ' [' + sb.ToString + ']');
|
||||
finally
|
||||
sb.Free;
|
||||
end;
|
||||
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.Body.Accept(Self);
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
||||
var
|
||||
arg: IAstNode;
|
||||
|
||||
Reference in New Issue
Block a user