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

Implemented basic C++ support #1052

Merged
merged 9 commits into from
Jul 6, 2023
Merged

Implemented basic C++ support #1052

merged 9 commits into from
Jul 6, 2023

Conversation

Ellen-Wittingen
Copy link

@Ellen-Wittingen Ellen-Wittingen commented Jul 6, 2023

This is the ground work to later support SYCL constructs (which I will start on after the summer holidays).

I implemented the following C++ constructs:

  • if-statements, while-loops, and for-loops with the following structure: for (int i = 0; i < max; i++) {}
  • math operators a + b, a - b, a * b, a / b, a % b, a++, a--, a += b, a -= b, a *= b, a /= b, a %= b
  • logical operators !a, not a, a && b, a || b, a == b, a != b, a < b, a <= b, a > b, a >= b
  • methods similar to the c implementation, allows abstract and fully implemented methods, and for them to be called
  • variable declarations, both local and global
  • arrays to the same extent as the c implementation. Elements can be assigned and read from arrays that are functions parameters.
  • pointers to the same extent as the c implementation. So declaration of pointers, but not getting their address with &
  • declaration and usage of namespaces
  • scoped blocks inside methods
  • the types bool, int, long, double, float, char, and void (literal string are recognised, but do not have the type char*, so cannot be used in practise)

See the files in examples/cpp/* for example usages

Also added a setup to implement SYCL class methods in the future. Implementing classes is to much work so I want to handle the sycl class methods I need in the following way: In the name resolution phase, when searching for what a name refers to, if in the name . is detected (so when it is a reference to a method or field of a class), the type of the name before the . is found (so the class). If the type is one of the supported sycl classes, the name is replaced with the namespace path to an equivalent method in a namespace in res/universal/res/cpp/sycl/sycl.hpp. For example, in

sycl::queue queue;
queue.submit(5);

queue.submit is replaced with VERCORS::sycl::queue::VERCORS__submit, which is declared in the custom sycl header file in res/universal/res/cpp/sycl/sycl.hpp. The name VERCORS is added in front of the namespace and methods to make them unique from user-defined c++ code, as method overloading is not supported.

See examples/sycl for an example of usage, res/universal/res/cpp/sycl/sycl.hpp for supported SYCL methods (only contains 2 methods for testing purposes at the moment), and src/col/vct/col/resolve/lang/CPP.scala line 89 and onward on the just described handling of sycl class methods.

Copy link
Member

@pieter-bos pieter-bos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I'll merge this immediately for the benefit of not accumulating merge conflicts over summer break, the comments can be addressed later.

src/col/vct/col/resolve/ctx/Referrable.scala Show resolved Hide resolved
src/col/vct/col/resolve/lang/CPP.scala Show resolved Hide resolved
src/col/vct/col/resolve/lang/CPP.scala Show resolved Hide resolved
Comment on lines +125 to +151
ctxTarget match {
case Some(ref) =>
nameSeq = nameSeq.drop(1);
var foundNamespace: Option[CPPNamespaceDefinition[G]] = Some(ref.decl)
var returnVal: Option[CPPNameTarget[G]] = None;
while (nameSeq.nonEmpty) {
if (foundNamespace.isEmpty) {
return None
}

if (nameSeq.length > 1) {
// Look for nested namespaces
foundNamespace = foundNamespace.get.declarations.collectFirst {
case namespace: CPPNamespaceDefinition[G] if namespace.name == nameSeq.head => namespace
}
} else {
// Look for final nameTarget
returnVal = foundNamespace.get.declarations.collectFirst {
case funcDef: CPPFunctionDefinition[G] if getDeclaratorInfo(funcDef.declarator).name == nameSeq.head => RefCPPFunctionDefinition(funcDef)
case globalDecl: CPPGlobalDeclaration[G] if getDeclaratorInfo(globalDecl.decl.inits.head.decl).name == nameSeq.head => RefCPPGlobalDeclaration(globalDecl, 0)
}
}
nameSeq = nameSeq.drop(1)
}
returnVal
case None => None
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be simplified if we add a node for ::, the left-hand side can then typically be resolved to a RefNamespaceDefinition. The right-hand side is then just one step: looking up a name in the (already resolved) namespace. I think this is fine for now though, we can discuss it more later.

@pieter-bos pieter-bos merged commit 0cfbe99 into dev Jul 6, 2023
14 checks passed
@pieter-bos pieter-bos deleted the sycl-rq1 branch October 11, 2023 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants