type Expr = Const Float | Var String| Add Expr Expr| Mult Expr Expr
list = [3,1,4]
polyX : List Float -> Expr
polyX coeffs = polyHelper <| map Const <| coeffs
polyHelper: List Expr -> Expr
polyHelper e = case e of
[x] -> x
(x::xs) -> Add x(Mult(Var "x")(polyHelper xs))
[] -> Const 1
type Instr = LoadImmediate RegisterNumber --put value here
RegisterValue --the value
| Addition RegisterNumber --put result here
RegisterNumber --first thing to add
RegisterNumber --first thing to multiply
| Multiply RegisterNumber --put result here
RegisterNumber --first thing to multiply
RegisterNumber --second thing to multiply
type RegisterNumber = Int
type RegisterValue = Float
expr2Code : Expr -> List Instr
expr2Code expr = e2C 1 expr
e2C result expr = case expr of
Const x -> ((LoadImmediate(result+2))x)
Add expr1 expr2 -> (Addition result result (result+1))::(e2C result expr2)++(e2C result expr1)
Mult expr1 expr2 -> (Mult result result(result+1))::(e2C result expr2)++(e2C result expr1)
Var x -> []
我在执行任务时遇到困难。
问题:
假设你将看到的唯一变量是x,它已经在寄存器2中。安排结果在计算结束时到达寄存器1,并使用寄存器3和4作为其他值,如需要。编写辅助函数e2C来完成。
我的T.A说我现在的代码会编译,但它不会解决问题。
任何人都可以告诉我如何修复代码,以便解决问题吗?
答案 0 :(得分:0)
嗯,你的TA错了,代码片段无法编译。这是一个编译版本:
type Expr
= Const Float
| Var String
| Add Expr Expr
| Mult Expr Expr
type Instr
= LoadImmediate RegisterNumber --put value here
RegisterValue --the value
| Addition RegisterNumber --put result here
RegisterNumber --first thing to add
RegisterNumber --first thing to multiply
| Multiply RegisterNumber --put result here
RegisterNumber --first thing to multiply
RegisterNumber --second thing to multiply
type alias RegisterNumber
= Int
type alias RegisterValue
= Float
list : List Float
list =
[3,1,4]
polyX : List Float -> Expr
polyX coeffs =
polyHelper <| List.map Const <| coeffs
polyHelper: List Expr -> Expr
polyHelper e =
case e of
[x] ->
x
(x::xs) ->
Add x (Mult (Var "x") (polyHelper xs))
[] ->
Const 1
expr2Code : Expr -> List Instr
expr2Code expr =
e2C 1 expr
e2C : RegisterNumber -> Expr -> List Instr
e2C result expr =
case expr of
Const x ->
[LoadImmediate (result+2) x]
Add expr1 expr2 ->
Addition result result (result+1)
:: e2C result expr2 ++ e2C result expr1
Mult expr1 expr2 ->
Multiply result result (result+1)
:: e2C result expr2 ++ e2C result expr1
Var x ->
[]
我已根据style guide更多地格式化了代码。在编译代码之前我发现了以下问题:
polyX
使用了不合格的map
函数,但没有导入,因此您应该使用限定的List.map
。 RegisterNumber
和RegisterValue
是别名。请使用type alias
,否则您需要为完全独立的类型Int
和Float
定义构造函数 RegisterNumber
和RegisterValue
而不是将它们与类型 Int and
Float`相关联。 Const
中的e2C
分支未返回列表,但case
的其他分支是。Mult
。 e2C
中的Mult
分支正在使用Multiply
代替Expr
作为结果,Instr
而不是[LoadImmediate freeRegister 0, Addition moveToThisRegister MoveFromThisRegister freeRegister]
。 免责声明:检查有关FRAUD的学校/课程规定。根据我的经验,学生只能提交他们自己编写的解决方案。关于解决方案的高级讨论通常都可以,复制代码很可能不行。根据您学校的欺诈规定,这个答案可能会进一步详细说明。引用你的消息来源并不总是足够的!
鉴于您可以执行三条指令,将结果从一个寄存器移动到另一个寄存器并不容易。这需要e2C
之类的虚假指令。因此,您不能优雅地创建精心编译的编译器,并且您可能不必这样做,因为您只需要完成辅助函数Expr
。
因此,我们正在寻求简单,非通用的解决方案。您将对您所获得的polyX
做一些假设。请注意,Const
仅生成具有某种程度不变的加法和乘法(Var
或{{1} }) 左手边。这是我们将要利用的财产。
因此,如果您先执行右侧表达式,并将该表达式赋予您给出的相同结果寄存器,那么您的左侧仍然有两个空闲寄存器(3和4)。只使用其中一个,然后在结果寄存器和所选的空闲寄存器之间进行操作。
当没有移动操作时,将变量x的值移动到不同的寄存器是一种丑陋。但是它相当通用,所以让我们使用剩下的空闲寄存器将0添加到变量x的值并将该值保存到我们应该将结果放入的寄存器中这为您提供了以下实现:
registerOfX : RegisterNumber
registerOfX = 2
freeRegister1 : RegisterNumber
freeRegister1 = 3
freeRegister2 : RegisterNumber
freeRegister2 = 4
e2C : RegisterNumber -> Expr -> List Instr
e2C resultRegister expr =
case expr of
Const value ->
[LoadImmediate resultRegister value]
Add expr1 expr2 ->
e2C resultRegister expr2
++ e2C freeRegister1 expr1
++ [Addition resultRegister freeRegister1 resultRegister]
Mult expr1 expr2 ->
e2C resultRegister expr2
++ e2C freeRegister1 expr1
++ [Multiply resultRegister freeRegister1 resultRegister]
Var "x" ->
[LoadImmediate freeRegister2 0, Addition resultRegister registerOfX freeRegister2]
Var _ ->
"Cannot handle "
++ toString expr
++ ", we only know of "
++ toString (Var "x")
|> Debug.crash
最后一点,因为这已经是一个很长的答案。您会发现此代码会产生一些冗余的LoadImmediate 4 0
指令。您可以通过执行LoadImmediate freeRegister2 0 :: case expr of ...
之类的操作,将信号指令添加到列表的前面。然后,您可以将变量x移动到一个指令中的寄存器。进一步最小化指令将需要额外的步骤,这些步骤最好在其他辅助函数中完成,或者您需要通过直接匹配Mult (Var "x") expr2
并直接使用变量x的寄存器来使代码不那么通用。