Go Type Inference Playground
This challenge asks you to build a simplified Go type inference engine. Type inference is a crucial feature in many programming languages, allowing the compiler to deduce the type of a variable or expression without explicit declaration. This reduces verbosity and improves developer productivity.
Problem Description
You need to implement a function InferType that takes a Go AST (Abstract Syntax Tree) node representing a variable declaration or assignment and infers its type. This challenge focuses on a subset of Go's type inference capabilities, specifically for simple assignments and declarations involving literals and basic types.
Key Requirements:
- The function should accept a
*ast.GenDeclnode (forvardeclarations) or an*ast.AssignStmtnode (for assignments). - It should infer the type of the declared or assigned variables based on the literal values provided.
- Handle integer literals (decimal, octal, hexadecimal), floating-point literals, and string literals.
- The function should return the inferred type as a
string(e.g., "int", "float64", "string"). - If type inference is not possible or ambiguous for the given node, the function should return an empty string or a specific indicator (e.g., "unknown").
Expected Behavior:
- For
var x = 10, infer "int". - For
var y = 3.14, infer "float64". - For
var z = "hello", infer "string". - For
a := 20, infer "int". - For
b := 1.23, infer "float64". - For
c := "world", infer "string". - For
var num int = 10, return the explicit type "int" (no inference needed in this specific case, but the function should still return the correct type).
Edge Cases to Consider:
- Declarations with multiple variables and multiple values.
- Declarations with multiple variables and a single value (which will be assigned to all).
- Assignments with multiple variables and multiple values.
- Assignments with multiple variables and a single value.
- Declarations without initial values (e.g.,
var x int). In this case, if a type is explicitly provided, return it; otherwise, return "unknown". - Declarations/assignments involving complex expressions or function calls (these are out of scope for this challenge and should result in "unknown").
Examples
Example 1: var declaration with a literal
Input AST Node:
Represents var x = 42
Output:
"int"
Explanation: The ast.BasicLit has a value 42 and Kind: token.INT. Go's default type for integer literals is int.
Example 2: Short variable declaration with a literal
Input AST Node:
Represents y := 3.14159
Output:
"float64"
Explanation: The ast.BasicLit has a value 3.14159 and Kind: token.FLOAT. Go's default type for floating-point literals is float64.
Example 3: var declaration with explicit type
Input AST Node:
Represents var name string = "Alice"
Output:
"string"
Explanation: The GenDecl has a Type field specifying string. The Name field for the identifier is "name". We should return the explicitly declared type.
Example 4: Assignment with multiple values
Input AST Node:
Represents a, b = 100, "Go"
Output:
["int", "string"] (assuming the function returns a slice of strings for assignments)
Explanation: The first value 100 is an integer literal, inferring "int". The second value "Go" is a string literal, inferring "string".
Constraints
- The input will be a valid Go AST node parsed from a small Go code snippet.
- Focus only on
ast.GenDecl(withTok == token.VAR) andast.AssignStmt(withTok == token.DEFINEortoken.ASSIGN). - Handle only
ast.BasicLitnodes for inferring types. - The maximum number of variables in a declaration/assignment will be 10.
- The inferred types will be limited to basic Go types: "int", "float64", "string", "bool".
Notes
- You will need to use the
go/astandgo/tokenpackages to parse and traverse the Go code. - Consider how Go handles default types for literals (e.g.,
10isint,3.14isfloat64,trueisbool,"hello"isstring). - For assignments where multiple variables are assigned a single value, that value's type should be inferred for all variables.
- This challenge is a simplified version of Go's type inference. Real-world Go type inference is much more complex, involving context, named types, and type inference within generic functions.