-
Notifications
You must be signed in to change notification settings - Fork 19
Draft: Understanding the Go Compiler ‐ Part 1: From AST to IR
xhd2015 edited this page Apr 7, 2024
·
2 revisions
Here is an illegal program that normal go compiler will fail to compile:
package debug
import (
"testing"
)
const N = 50
func TestPatchConstInAssignmentShouldWork(t *testing.T) {
n := N
getN(n)
}
func printN(n int64) {
fmt.Printf("n=%d\n", n)
}
Run:
go test ./
Output:
demo_test.go:20:7: cannot use n (variable of type int) as int64 value in argument to printN
FAIL github.com/xhd2015/xgo/runtime/test/debug [build failed]
As the message says, n
has type int
, while printN
accepts int64
, without a conversion, go refused to compile the program.
Our goal is to make the above program compile, without modifying the source code.
We will dig in depth the go compiler, and some of its code.
In this process, we will understand how go process the source code internally, and what stages are invovled.
Draft:
N type
__trap_x() N
CallExpr{
TypeCast {
fn: Type,
Args: [CallExpr{
fn: __trap_const,
args: (pkg,name,value)
}]
}
}
int64(__trap().(int))
X.(int) assert expr Type=int,value=nil
helper:
a typeof helper
Typeof(x*y) --> does nothing, instead it extracts
// best compatibility
SimpleConvert(__trap().(int))
// not always working
var x Typeof(expr) = d
Three kinds:
- assignment
- binary operation
- switch case comparision