Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Draft: Understanding the Go Compiler ‐ Part 1: From AST to IR

xhd2015 edited this page Apr 7, 2024 · 2 revisions

Introduction

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.

Goal

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.

The AST

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

Implicit Type Conversions

Two kinds: assignment and binary operation

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /