This commit is contained in:
parent
72ace483e4
commit
0eaeb726b9
8 changed files with 112 additions and 101 deletions
|
@ -27,8 +27,14 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
}
|
||||
|
||||
f.Dependencies.Add(function)
|
||||
v := f.AppendFunction(function.UniqueName, function.Type, function.IsExtern())
|
||||
v.SetSource(expr.Source)
|
||||
|
||||
v := f.Append(&ssa.Function{
|
||||
UniqueName: function.UniqueName,
|
||||
Typ: function.Type,
|
||||
IsExtern: function.IsExtern(),
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
|
@ -41,26 +47,33 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
v := f.AppendInt(number)
|
||||
v.SetSource(expr.Source)
|
||||
v := f.Append(&ssa.Int{
|
||||
Int: number,
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
return v, nil
|
||||
|
||||
case token.String:
|
||||
data := expr.Token.Bytes(f.File.Bytes)
|
||||
data = Unescape(data)
|
||||
|
||||
length := f.AppendInt(len(data))
|
||||
length.SetSource(expr.Source)
|
||||
length := f.Append(&ssa.Int{
|
||||
Int: len(data),
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
pointer := f.AppendBytes(data)
|
||||
pointer.SetSource(expr.Source)
|
||||
pointer := f.Append(&ssa.Bytes{
|
||||
Bytes: data,
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
v := f.Append(&ssa.Struct{
|
||||
Arguments: []ssa.Value{pointer, length},
|
||||
Typ: types.String,
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
v.SetSource(expr.Source)
|
||||
return v, nil
|
||||
}
|
||||
|
||||
|
@ -75,17 +88,6 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
if children[0].Token.Kind == token.Identifier {
|
||||
funcName := children[0].String(f.File.Bytes)
|
||||
|
||||
if funcName == "len" {
|
||||
identifier := children[1].String(f.File.Bytes)
|
||||
length, exists := f.Identifiers[identifier+".len"]
|
||||
|
||||
if !exists {
|
||||
return nil, errors.New(&UnknownIdentifier{Name: identifier + ".len"}, f.File, expr.Token.Position)
|
||||
}
|
||||
|
||||
return length, nil
|
||||
}
|
||||
|
||||
if funcName == "syscall" {
|
||||
children = children[1:]
|
||||
isSyscall = true
|
||||
|
@ -111,47 +113,57 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
}
|
||||
|
||||
return f.Append(syscall), nil
|
||||
} else {
|
||||
name := args[0].(*ssa.Function).UniqueName
|
||||
fn := f.All.Functions[name]
|
||||
parameters := args[1:]
|
||||
}
|
||||
|
||||
if len(parameters) != len(fn.Input) {
|
||||
return nil, errors.New(&ParameterCountMismatch{Function: name, Count: len(parameters), ExpectedCount: len(fn.Input)}, f.File, expr.Source[0].Position)
|
||||
}
|
||||
name := args[0].(*ssa.Function).UniqueName
|
||||
fn := f.All.Functions[name]
|
||||
parameters := args[1:]
|
||||
|
||||
for i, param := range slices.Backward(parameters) {
|
||||
if !types.Is(param.Type(), fn.Input[i].Typ) {
|
||||
_, isPointer := fn.Input[i].Typ.(*types.Pointer)
|
||||
if len(parameters) != len(fn.Input) {
|
||||
return nil, errors.New(&ParameterCountMismatch{Function: name, Count: len(parameters), ExpectedCount: len(fn.Input)}, f.File, expr.Source[0].Position)
|
||||
}
|
||||
|
||||
if isPointer {
|
||||
number, isInt := param.(*ssa.Int)
|
||||
for i, param := range slices.Backward(parameters) {
|
||||
if !types.Is(param.Type(), fn.Input[i].Typ) {
|
||||
_, isPointer := fn.Input[i].Typ.(*types.Pointer)
|
||||
|
||||
if isInt && number.Int == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if isPointer {
|
||||
number, isInt := param.(*ssa.Int)
|
||||
|
||||
// Temporary hack to allow int64 -> uint32 conversion
|
||||
if types.Is(param.Type(), types.AnyInt) && types.Is(fn.Input[i].Typ, types.AnyInt) {
|
||||
if isInt && number.Int == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
return nil, errors.New(&TypeMismatch{
|
||||
Encountered: param.Type().Name(),
|
||||
Expected: fn.Input[i].Typ.Name(),
|
||||
ParameterName: fn.Input[i].Name,
|
||||
}, f.File, param.Start())
|
||||
}
|
||||
}
|
||||
|
||||
if fn.IsExtern() {
|
||||
return f.Append(&ssa.CallExtern{Arguments: args, Source: ssa.Source(expr.Source)}), nil
|
||||
}
|
||||
// Temporary hack to allow int64 -> uint32 conversion
|
||||
if types.Is(param.Type(), types.AnyInt) && types.Is(fn.Input[i].Typ, types.AnyInt) {
|
||||
continue
|
||||
}
|
||||
|
||||
return f.Append(&ssa.Call{Arguments: args, Source: ssa.Source(expr.Source)}), nil
|
||||
return nil, errors.New(&TypeMismatch{
|
||||
Encountered: param.Type().Name(),
|
||||
Expected: fn.Input[i].Typ.Name(),
|
||||
ParameterName: fn.Input[i].Name,
|
||||
}, f.File, param.Start())
|
||||
}
|
||||
}
|
||||
|
||||
if fn.IsExtern() {
|
||||
v := f.Append(&ssa.CallExtern{
|
||||
Arguments: args,
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
v := f.Append(&ssa.Call{
|
||||
Arguments: args,
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
return v, nil
|
||||
|
||||
case token.Dot:
|
||||
left := expr.Children[0]
|
||||
right := expr.Children[1]
|
||||
|
@ -167,8 +179,12 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
return nil, errors.New(&UnknownStructField{StructName: structure.Name(), FieldName: rightText}, f.File, right.Token.Position)
|
||||
}
|
||||
|
||||
v := f.Append(&ssa.StructField{Struct: identifier, Field: field})
|
||||
v.SetSource(expr.Source)
|
||||
v := f.Append(&ssa.StructField{
|
||||
Struct: identifier,
|
||||
Field: field,
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
|
@ -182,13 +198,19 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
f.Dependencies.Add(function)
|
||||
}
|
||||
|
||||
v := f.AppendFunction(function.UniqueName, function.Type, function.IsExtern())
|
||||
v.SetSource(expr.Source)
|
||||
v := f.Append(&ssa.Function{
|
||||
UniqueName: function.UniqueName,
|
||||
Typ: function.Type,
|
||||
IsExtern: function.IsExtern(),
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return nil, errors.New(&UnknownIdentifier{Name: label}, f.File, left.Token.Position)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
default:
|
||||
panic("not implemented")
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue