Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development #65

Merged
merged 8 commits into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions playground/examples/quantum_fourier_transform.qut
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ qubit x_1 = 0q;
qubit x_2 = 1q;
qubit x_3 = 1q;

float pi = 3.1415926535;

//QFT
hadamard x_1;
mcp x_1,x_2 by (3.14/2);
mcp x_1,x_2 by (3.14/4);
mcp x_1,x_2 by (pi/2);
mcp x_1,x_2 by (pi/4);

hadamard x_2;
mcp x_2,x_3 by (3.14/2);
mcp x_2,x_3 by (pi/2);

hadamard x_3;

Expand All @@ -19,11 +21,11 @@ swap x_3,x_1;
//inverse

hadamard x_1;
mcp x_1,x_2 by (-3.14/2);
mcp x_1,x_2 by (-3.14/4);
mcp x_1,x_2 by (-pi/2);
mcp x_1,x_2 by (-pi/4);

hadamard x_2;
mcp x_2,x_3 by (-3.14/2);
mcp x_2,x_3 by (-pi/2);

hadamard x_3;
swap x_3,x_1;
Expand Down
8 changes: 5 additions & 3 deletions playground/examples/test.qut
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
qubit a = 0q;
bool b = a;
int a = 10;
int b = -4;

print b;
int c = a + b;

print c;
2 changes: 1 addition & 1 deletion qutes-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"author": "Gabriele Messina",
"publisher": "GabrieleMessina",
"license": "MIT",
"version": "1.1.4",
"version": "1.1.6",
"engines": {
"vscode": "^1.52.0"
},
Expand Down
4 changes: 2 additions & 2 deletions qutes-vscode/syntaxes/qutes.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
},
{
"name": "keyword.operator.qutes",
"match": "(\\*|\\/|\\+|\\-|==|>|>=|<|<=|=)|\\b(not|pauliy|pauliz|grover|mcz|mcx|mcp|swap|hadamard|measure|print|barrier)\\b"
"match": "(\\*|/|%|\\+|\\-|==|!=|>|>=|<|<=|=)|\\b(and|or|not|pauliy|pauliz|grover|mcz|mcx|mcp|mcy|swap|hadamard|measure|print|barrier)\\b|(\\+\\+|\\-\\-|\\+=|\\-=|\\*=|/=|&=)"
},
{
"name": "storage.type.qutes",
"match": "\\b(qustring|quint|qubit|int|string|bool|void)\\b"
"match": "\\b(qustring|quint|qubit|int|string|bool|void|float)\\b"
},
{
"name": "punctuation.terminator.qutes",
Expand Down
4 changes: 3 additions & 1 deletion qutes.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"cSpell.words": [
"Antlr",
"Qiskit",
"qustring"
"qustring",
"qubit",
"quint",
],
"pylint.importStrategy": "fromEnvironment",
"python.testing.cwd": "./src",
Expand Down
13 changes: 12 additions & 1 deletion specification/grammar/qutes_lexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ VOID_TYPE : 'void' ;
RETURN : 'return' ;
MULTIPLY : '*' ;
DIVIDE : '/' ;
MODULE : '%' ;
ADD : '+' ;
SUB : '-' ;
NOT : 'not' ;
AND : 'and' ;
OR : 'or' ;
BY : 'by' ;
SWAP : 'swap' ;
PAULIY : 'pauliy' ;
Expand All @@ -33,11 +36,19 @@ MEASURE : 'measure' ;
PRINT : 'print' ;
BARRIER : 'barrier' ;
EQUAL : '==' ;
NOT_EQUAL : '!=' ;
GREATER : '>' ;
GREATEREQUAL : '>=' ;
LOWER : '<' ;
LOWEREQUAL : '<=' ;
ASSIGN : '=' ;
AUTO_INCREMENT : '++' ;
AUTO_DECREMENT : '--' ;
AUTO_SUM : '+=' ;
AUTO_SUB : '-=' ;
AUTO_MULTIPLY : '*=' ;
AUTO_DIVIDE : '/=' ;
AUTO_MODULE : '%=' ;
END_OF_STATEMENT : ';' ;
VAR_STATEMENT : 'var' ;
FOR_STATEMENT : 'for' ;
Expand Down Expand Up @@ -98,7 +109,7 @@ BOOL_LITERAL
;

INT_LITERAL
: DIGIT+
: MATH_SIGN? DIGIT+
;

FLOAT_LITERAL
Expand Down
91 changes: 39 additions & 52 deletions specification/grammar/qutes_parser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -16,77 +16,57 @@ statement
| IF_STATEMENT expr statement ELSE_STATEMENT statement #IfElseStatement
| WHILE_STATEMENT expr statement #WhileStatement
| DO_STATEMENT statement WHILE_STATEMENT expr #DoWhileStatement
| block #BlockStatement
| CURLY_PARENTHESIS_OPEN statement* CURLY_PARENTHESIS_CLOSE #BlockStatement
| variableType functionName ROUND_PARENTHESIS_OPEN functionDeclarationParams? ROUND_PARENTHESIS_CLOSE statement #FunctionStatement
| variableDeclaration END_OF_STATEMENT #DeclarationStatement
| qualifiedName ASSIGN expr END_OF_STATEMENT #AssignmentStatement
| RETURN expr END_OF_STATEMENT #ReturnStatement
| expr END_OF_STATEMENT #ExpressionStatement
| (MEASURE | BARRIER) #FactStatement
| END_OF_STATEMENT #EmptyStatement
;

block
: CURLY_PARENTHESIS_OPEN statement* CURLY_PARENTHESIS_CLOSE
;

functionDeclarationParams
: variableDeclaration (COMMA functionDeclarationParams)?
;

//TODO: rename variableName to variableDeclarationName
variableDeclaration
: variableType variableName (ASSIGN expr)?
;

functionCallParams
: qualifiedName (COMMA functionCallParams)?
;

expr
: term
| functionCall
| test
| parenExpr
| groverExpr
;

groverExpr
: termList op=IN_STATEMENT qualifiedName
;

functionCall //Function name should be a qualifiedName here.
: functionName ROUND_PARENTHESIS_OPEN functionCallParams? ROUND_PARENTHESIS_CLOSE
: ROUND_PARENTHESIS_OPEN expr ROUND_PARENTHESIS_CLOSE #ParentesizeExpression
| literal #LiteralExpression
| qualifiedName #QualifiedNameExpression
// Array access
| functionName ROUND_PARENTHESIS_OPEN functionCallParams? ROUND_PARENTHESIS_CLOSE #FunctionCallExpression
| expr op=(AUTO_INCREMENT | AUTO_DECREMENT) #PostfixOperator
| op=(NOT | ADD | SUB | AUTO_INCREMENT | AUTO_DECREMENT) expr #PrefixOperator
// cast operation
| expr op=(MULTIPLY | DIVIDE | MODULE) expr #MultiplicativeOperator
| expr op=(ADD | SUB) expr #SumOperator
| expr op=(GREATEREQUAL | LOWEREQUAL | GREATER | LOWER ) expr #RelationalOperator
| expr op=(EQUAL | NOT_EQUAL) expr #EqualityOperator
| expr op=AND expr #LogicAndOperator
| expr op=OR expr #LogicOrOperator
// | <assoc = right> expr op=(AUTO_SUM | AUTO_DECREMENT | AUTO_MODULE | AUTO_DIVIDE | AUTO_MODULE) expr #AutoAssignmentOperator
| op=(MCX | MCZ | MCY | SWAP) termList #MultipleUnaryOperator
| op=(PRINT | PAULIY | PAULIZ | HADAMARD | MEASURE) expr #UnaryOperator
| op=MCP termList BY expr #MultipleUnaryPhaseOperator
| termList op=IN_STATEMENT qualifiedName #GroverOperator
;

parenExpr
: ROUND_PARENTHESIS_OPEN expr ROUND_PARENTHESIS_CLOSE
functionCallParams
: (literal | qualifiedName) (COMMA functionCallParams)?
;

test
: term
| term op=(GREATER | LOWER | EQUAL | GREATEREQUAL | LOWEREQUAL) term
termList
: (literal | qualifiedName) (COMMA termList)?
;

term
: term op=(MULTIPLY | DIVIDE) term #BinaryPriorityOperator
| term op=(ADD | SUB) term #BinaryOperator
| op=(PRINT | NOT | PAULIY | PAULIZ | HADAMARD | MEASURE | ADD | SUB) term #UnaryOperator
| op=(MCX | MCZ | MCY | SWAP) termList #MultipleUnaryOperator
| op=MCP termList BY expr #MultipleUnaryPhaseOperator
| (boolean
| integer
| float
| qubit
| quint
| qustring
variableType
: type
| qualifiedName
| MEASURE
| BARRIER
| string) #IdentityOperator
;

termList
: term (COMMA termList)?
;

type
Expand All @@ -100,13 +80,10 @@ type
| VOID_TYPE
;

variableType
: type
| qualifiedName
;

qualifiedName
: SYMBOL_LITERAL (DOT SYMBOL_LITERAL)*
| variableName
| functionName
;

variableName
Expand All @@ -117,6 +94,16 @@ functionName
: SYMBOL_LITERAL
;

literal
: boolean
| integer
| float
| qubit
| quint
| qustring
| string
;

string
: STRING_LITERAL
;
Expand Down
64 changes: 64 additions & 0 deletions src/grammar_frontend/expression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from grammar_frontend.qutes_parser import QutesParser as qutes_parser
from symbols.scope_tree_node import ScopeTreeNode
from symbols.symbol import Symbol, SymbolClass
from symbols.scope_handler import ScopeHandlerForSymbolsUpdate
from symbols.variables_handler import VariablesHandler
from quantum_circuit import QuantumCircuitHandler
from grammar_frontend.qutes_base_visitor import QutesBaseVisitor

class QutesGrammarExpressionVisitor(QutesBaseVisitor):
def __init__(self, symbols_tree:ScopeTreeNode, quantum_circuit_handler : QuantumCircuitHandler, scope_handler:ScopeHandlerForSymbolsUpdate, variables_handler:VariablesHandler, verbose:bool = False):
super().__init__(symbols_tree, quantum_circuit_handler, scope_handler, variables_handler, verbose)

def visitExpr(self, ctx:qutes_parser.ExprContext):
return self.visitChildren(ctx)

def visitParentesizeExpression(self, ctx:qutes_parser.ParentesizeExpressionContext):
return self.visit(ctx.expr())

def visitLiteralExpression(self, ctx:qutes_parser.LiteralExpressionContext):
return self.visit(ctx.literal())

def visitQualifiedNameExpression(self, ctx:qutes_parser.QualifiedNameExpressionContext):
return self.visit(ctx.qualifiedName())

def visitFunctionCallExpression(self, ctx:qutes_parser.FunctionCallExpressionContext):
function_name = self.visit(ctx.functionName())
function_params:list[Symbol] = []
if(ctx.functionCallParams()):
function_params = self.visit(ctx.functionCallParams())
result:Symbol = self.__visitFunctionCall(function_name, function_params, ctx.start.tokenIndex)
#TODO: staff commented for make return value work for quantum variable, do some tests to assure the behaviour is correct
# function_symbol = self.variables_handler.get_function_symbol(function_name, ctx.start.tokenIndex, function_params)
# self.quantum_cirtcuit_handler.push_compose_circuit_operation(function_symbol.quantum_function)
return result

def __visitFunctionCall(self, function_name, function_params, tokenIndex):
self.scope_handler.start_function() #To avoid block statement to push its scope

function_symbol = self.variables_handler.get_function_symbol(function_name, tokenIndex, function_params)

scope_to_restore_on_exit = self.scope_handler.current_symbols_scope
self.scope_handler.current_symbols_scope = function_symbol.inner_scope

default_params_to_restore_on_exit = function_symbol.function_input_params_definition.copy()

symbol_params_to_push = []
for index in range(len(function_params)):
symbol_to_push = default_params_to_restore_on_exit[index]
symbol_to_push.value = function_params[index].value
symbol_to_push.quantum_register = function_params[index].quantum_register
symbol_params_to_push.append(symbol_to_push)
[symbol for symbol in function_symbol.inner_scope.symbols if symbol.symbol_class == SymbolClass.FunctionSymbol][:len(function_params)] = symbol_params_to_push

#TODO: staff commented for make return value work for quantum variable, do some tests to assure the behaviour is correct
# self.quantum_cirtcuit_handler.start_quantum_function()
result = self.visitChildren(function_symbol.value)
# gate = self.quantum_cirtcuit_handler.end_quantum_function(function_symbol.name)
# function_symbol.quantum_function = gate

self.scope_handler.current_symbols_scope = scope_to_restore_on_exit
[symbol for symbol in function_symbol.inner_scope.symbols if symbol.symbol_class == SymbolClass.FunctionSymbol][:len(function_params)] = default_params_to_restore_on_exit

self.scope_handler.end_function()
return result
Loading
Loading