Skip to content
/ k Public

K (K-lang) is a strongly-typed, C-like programming language that I am writing to learn how to write a compiler. It is written in Go and uses LLVM as a backend.

License

Notifications You must be signed in to change notification settings

klvnptr/k

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

K-lang

Intro

K (K-lang) is a strongly-typed, C-like programming language that I am writing to learn how to write a compiler. It is written in Go and uses LLVM as a backend.

All it can do right now is to run bunch of tests. See ast/*_test.go files.

If you want to run the tests, run.

go test ./...

One of the goals it to take and adopt as many test cases possible from the standard c-testsuite and have K pass them. See the runner in ast/k_testsuite_test.go and the adapted test cases in testsuite folder.

K (or K-lang) is named after the inital of Konstruktor, a fantastic product engineering team in Budapest, Hungary that I am a part of.

Examples

K can link to standard C libraries and call functions from them. Here is an example of a program that calls the printf function from the standard C library.

i64 printf(i8 *fmt, ...);

i64 fib(i64 n) {
	if (n < 2) {
		return n;
	}

	return fib(n - 1) + fib(n - 2);
}

i64 main() {
	i64 i = 0;
	
	while (i++ < 6)
		printf("fib(%d) = %d\n", i, fib(i));
	
	return 0;
}

And it's output:

fib(1) = 1
fib(2) = 1
fib(3) = 2
fib(4) = 3
fib(5) = 5
fib(6) = 8

K already has a fine pointer arithmetic implementation. Here is an example of a program that uses it to reverse a string.

i64 printf(i8 *fmt, ...);

i8* strrev(i8 *s) {
    i8 *p = s;
    i8 *q = s;
    i8 tmp;

    while (*q != (i8)0) {
        q++;
    }

    q--;

    while (p < q) {
        tmp = *p;
        *p = *q;
        *q = tmp;
        p++;
        q--;
    }

    return s;
}

i64 main() {
    i8 *s = "hello";
    printf("%s", strrev(s));
    
    return 0;
}

And it's output:

olleh

Architecture

  1. alecthomas/participle is used in the parser package to parse the source code into an AST.
  2. Transform() called on the AST and returns a new AST that is easier to work with in the next (code generation step) step.
  3. In the ast package llir/llvm is used for code generation. It is a Go package that generates easy to read, plain text LLVM IR.
  4. We call llc to compile the LLVM IR into machine code.

Todo

Many todos. Here is a list of some of them:

  • implement more operators from C
  • convert operators to head + tail
  • implement arrays
    • partially implemented, needs more testing
  • implement globals
  • sizeof should accept expressions
  • struct assign {.a = 1, .b = 2}
  • continue, break
  • for loop
  • +=, -=, *=, /=

Useful Resources

Code Generation

  • LLVM IR and Go This is a good introduction to LLVM IR and how to use the llir/llvm package to generate LLVM IR in Go. This inspired me to start writing this compiler.

C syntax

LLVM IR

EBNF

  • General Extended BNF syntax This is a good introduction to EBNF. Can be useful to understand participle's EBNF-like syntax in the Go structs.

About

K (K-lang) is a strongly-typed, C-like programming language that I am writing to learn how to write a compiler. It is written in Go and uses LLVM as a backend.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages