Low-level: Assembler, CIL,
High-level: any language that is object-oriented or supports complex data types.

This type of classification, although slightly losing relevance since the vast majority of languages can now be classified as high-level, is still in place since low-level languages exist.

This classification was relevant in the early days of computers, when the number of available compilers could be counted on the fingers, and to write, for example, a keyboard driver in Assembler could be used as a pastime in your spare time.

Recall that Assembler is a language whose commands correspond as much as possible to the commands of the microprocessor itself, and that allows to process data with size one, two or four bytes, so that it is very difficult to represent complex data types in it. But the Assembler language has no equal in speed of program execution.

The CIL language, already mentioned above, is in a sense an assembly language, but for the .Net system. CIL commands are converted by the .Net JIT compiler into microprocessor instruction sets, depending on the type of microprocessor itself on which .Net is installed. As a rule, a CIL program is the result of compiling a program written in one of the .Net high-level languages.

Moreover, CIL is a special language. Writing a program directly in it may be too long. Programs in this language are generated by compilers and used by the .Net platform software. That is why it is considered a programming language for machines rather than humans.