<commit_before>package main

var TypeIota int

type Type struct {
	Name, Push, Pop string
	Int int
	User bool
	
	Detail *UserType
}

func (t Type) IsUser() Type {
	if t.User {
		return t
	} else {
		return Undefined
	}
}

type UserType struct {	
	Elements []Type
	Table map[string]int
	SubElements map[int]Type
}

func NewUserType(name string) Type {
	t := NewType(name, "SHARE", "GRAB")
	t.User = true
	t.Detail = new(UserType)
	t.Detail.Table = make(map[string]int)
	return t
}

func NewType(name string, options ...string) Type {
	var t Type
	t.Name = name
	
	if len(options) == 2 {
		t.Pop = options[1]
		t.Push = options[0]
	}
	
	t.Int = TypeIota
	TypeIota++
	
	return t
}

var Undefined = NewType("undefined")
var Number = NewType("number", "PUSH", "PULL")
var Letter = NewType("letter", "PUSH", "PULL")
var Text = NewType("text", "SHARE", "GRAB")
var Array = NewType("array", "SHARE", "GRAB")
var Itype = NewType("type", "PUSH", "PULL")
var User = NewType("usertype", "SHARE", "GRAB")
var Pipe = NewType("pipe", "RELAY", "TAKE")
var Func = NewType("function", "RELAY", "TAKE")
var Something = NewUserType("Something")

var Variadic = NewFlag()

func (ic *Compiler) ScanSymbolicType() Type {
	var result Type = Undefined
	var symbol = ic.Scan(0)
	switch symbol {
		case "{":
			result = User
			ic.Scan('}')
		case "[":
			result = Array
			ic.Scan(']')
		case `""`:
			result = Text
		case "'":
			result = Letter
			ic.Scan('\'')
		case "|":
			result = Pipe
			ic.Scan('|')
		case "(":
			result = Func
			ic.Scan(')')
		case "<":
			result = Itype
			ic.Scan('>')
		case ".":
			result = Variadic
			ic.Scan('.')
		default:
			result = Number
			ic.NextToken = symbol
			return result
	}
	return result
}

func (ic *Compiler) ScanType() {
	var name = ic.Scan(Name)
	t := NewUserType(name)
	
	ic.Scan('{')
	//What are the elements?
	for {
		var token = ic.Scan(0)
		if token == "}" {
			break
		}
		if token != "," && token != "\n" {
			ic.NextToken = token
		}
		
		MemberType := ic.ScanSymbolicType()
		
		ident := ic.Scan(Name)
		if ident == "}" {
			break
		}
		t.Detail.Elements = append(t.Detail.Elements, MemberType)
		t.Detail.Table[ident] = len(t.Detail.Elements)-1
		
	}
	ic.DefinedTypes[name] = t

	ic.LastDefinedType = t
}

func (ic *Compiler) ScanConstructor() string {
	var name = ic.Scan(Name)
					
	if _, ok := ic.DefinedTypes[name]; !ok {
		ic.RaiseError(name+" is an unrecognised type!")
	}
	
	var token = ic.Scan(0)
	
	if ic.Peek() == ")" && token == "(" {
		ic.ExpressionType = InFunction
		ic.NextToken = "("
		return name
	}
	
	var array = ic.Tmp("constructor")
	
	ic.Assembly("ARRAY ", array)
	//This is effectively a constructor.
	if token == "(" {
		var i int
		for {
			ic.Assembly("PLACE ", array)
			ic.Assembly("PUT %v", ic.ScanExpression())
			if i >= len(ic.DefinedTypes[name].Detail.Elements) {
				ic.RaiseError("Too many arguments passed to constructor!")
			}
			if ic.ExpressionType != ic.DefinedTypes[name].Detail.Elements[i] {
				ic.RaiseError("Mismatched types! Argument (%v) of constructor should be '%v'", i+1, 
					ic.DefinedTypes[name].Detail.Elements[i])
			}
			token = ic.Scan(0)
			if token == ")" {
				break
			} else if token != "," {
				ic.Expecting(",")
			}
			i++
		}
	} else if token == "\n" {
		for range ic.DefinedTypes[name].Detail.Elements {
			ic.Assembly("PUT 0")
		}
	} else {<commit_msg>Fix constructor bug.<commit_after>package main

var TypeIota int

type Type struct {
	Name, Push, Pop string
	Int int
	User bool
	
	Detail *UserType
}

func (t Type) IsUser() Type {
	if t.User {
		return t
	} else {
		return Undefined
	}
}

type UserType struct {	
	Elements []Type
	Table map[string]int
	SubElements map[int]Type
}

func NewUserType(name string) Type {
	t := NewType(name, "SHARE", "GRAB")
	t.User = true
	t.Detail = new(UserType)
	t.Detail.Table = make(map[string]int)
	return t
}

func NewType(name string, options ...string) Type {
	var t Type
	t.Name = name
	
	if len(options) == 2 {
		t.Pop = options[1]
		t.Push = options[0]
	}
	
	t.Int = TypeIota
	TypeIota++
	
	return t
}

var Undefined = NewType("undefined")
var Number = NewType("number", "PUSH", "PULL")
var Letter = NewType("letter", "PUSH", "PULL")
var Text = NewType("text", "SHARE", "GRAB")
var Array = NewType("array", "SHARE", "GRAB")
var Itype = NewType("type", "PUSH", "PULL")
var User = NewType("usertype", "SHARE", "GRAB")
var Pipe = NewType("pipe", "RELAY", "TAKE")
var Func = NewType("function", "RELAY", "TAKE")
var Something = NewUserType("Something")

var Variadic = NewFlag()

func (ic *Compiler) ScanSymbolicType() Type {
	var result Type = Undefined
	var symbol = ic.Scan(0)
	switch symbol {
		case "{":
			result = User
			ic.Scan('}')
		case "[":
			result = Array
			ic.Scan(']')
		case `""`:
			result = Text
		case "'":
			result = Letter
			ic.Scan('\'')
		case "|":
			result = Pipe
			ic.Scan('|')
		case "(":
			result = Func
			ic.Scan(')')
		case "<":
			result = Itype
			ic.Scan('>')
		case ".":
			result = Variadic
			ic.Scan('.')
		default:
			result = Number
			ic.NextToken = symbol
			return result
	}
	return result
}

func (ic *Compiler) ScanType() {
	var name = ic.Scan(Name)
	t := NewUserType(name)
	
	ic.Scan('{')
	//What are the elements?
	for {
		var token = ic.Scan(0)
		if token == "}" {
			break
		}
		if token != "," && token != "\n" {
			ic.NextToken = token
		}
		
		MemberType := ic.ScanSymbolicType()
		
		ident := ic.Scan(Name)
		if ident == "}" {
			break
		}
		t.Detail.Elements = append(t.Detail.Elements, MemberType)
		t.Detail.Table[ident] = len(t.Detail.Elements)-1
		
	}
	ic.DefinedTypes[name] = t

	ic.LastDefinedType = t
}

func (ic *Compiler) ScanConstructor() string {
	var name = ic.Scan(Name)
					
	if _, ok := ic.DefinedTypes[name]; !ok {
		ic.RaiseError(name+" is an unrecognised type!")
	}
	
	var token = ic.Scan(0)
	
	if ic.Peek() == ")" && token == "(" {
		ic.ExpressionType = InFunction
		ic.NextToken = "("
		return name
	}
	
	var array = ic.Tmp("constructor")
	
	ic.Assembly("ARRAY ", array)
	//This is effectively a constructor.
	if token == "(" {
		var i int
		for {
			var expr = ic.ScanExpression()
			ic.Assembly("PLACE ", array)
			ic.Assembly("PUT %v", expr)
			if i >= len(ic.DefinedTypes[name].Detail.Elements) {
				ic.RaiseError("Too many arguments passed to constructor!")
			}
			if ic.ExpressionType != ic.DefinedTypes[name].Detail.Elements[i] {
				ic.RaiseError("Mismatched types! Argument (%v) of constructor should be '%v'", i+1, 
					ic.DefinedTypes[name].Detail.Elements[i])
			}
			token = ic.Scan(0)
			if token == ")" {
				break
			} else if token != "," {
				ic.Expecting(",")
			}
			i++
		}
	} else if token == "\n" {
		for range ic.DefinedTypes[name].Detail.Elements {
			ic.Assembly("PUT 0")
		}
	} else {
{'fraction_non_alphanumeric': 0.16943127962085308, 'fraction_numerical': 0.002962085308056872, 'mean_word_length': 3.1505838967424706, 'pattern_counts': {'":': 14, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3654320', 'n_tokens_mistral': 2818, 'n_tokens_neox': 2507, 'n_words': 637}