Skip to content

Commit 3a67d70

Browse files
authored
Merge pull request #56 from qianmoQ/dev-25.0.4
feat (language): 支持 Haskell 语言
2 parents f97dc5d + 3eab0f4 commit 3a67d70

File tree

11 files changed

+195
-4
lines changed

11 files changed

+195
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ CodeForge 是一款轻量级、高性能的桌面代码执行器,专为开发
3030
<img src="public/icons/css.svg" width="60" alt="CSS">
3131
<img src="public/icons/go.svg" width="60" alt="Go">
3232
<img src="public/icons/groovy.svg" width="60" alt="Groovy">
33+
<img src="public/icons/haskell.svg" width="60" alt="Haskell">
3334
<img src="public/icons/html.svg" width="60" alt="HTML">
3435
<img src="public/icons/java.svg" width="60" alt="Java">
3536
<img src="public/icons/javascript-browser.svg" width="60" alt="JavaScript (Browser)">

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "codeforge",
33
"private": true,
4-
"version": "25.0.3",
4+
"version": "25.0.4",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

public/icons/haskell.svg

Lines changed: 5 additions & 0 deletions
Loading

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "CodeForge"
3-
version = "25.0.3"
3+
version = "25.0.4"
44
description = "CodeForge 是一款轻量级、高性能的桌面代码执行器,专为开发者、学生和编程爱好者设计。"
55
authors = ["devlive-community"]
66
edition = "2024"

src-tauri/src/examples/haskell.hs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
-- Haskell示例代码 - CodeForge 代码执行环境
2+
3+
import Data.List (intercalate)
4+
5+
main :: IO ()
6+
main = do
7+
putStrLn "🎉 欢迎使用 CodeForge!"
8+
putStrLn "Welcome to CodeForge!"
9+
putStrLn ""
10+
11+
putStrLn "========================================="
12+
putStrLn " CodeForge Haskell "
13+
putStrLn "========================================="
14+
putStrLn ""
15+
16+
-- 基本输出示例
17+
putStrLn "✅ Haskell运行成功! (Haskell is working!)"
18+
putStrLn "⚡ 这是Haskell程序 (This is Haskell program)"
19+
putStrLn ""
20+
21+
-- 变量操作
22+
let name = "CodeForge"
23+
version = "Haskell"
24+
number1 = 10
25+
number2 = 20
26+
result = number1 + number2
27+
28+
putStrLn "🔢 简单计算 (Simple calculation):"
29+
putStrLn $ show number1 ++ " + " ++ show number2 ++ " = " ++ show result
30+
putStrLn ""
31+
32+
-- 字符串操作
33+
putStrLn "📝 字符串操作 (String operations):"
34+
putStrLn $ "平台名称 (Platform): " ++ name
35+
putStrLn $ "语言版本 (Language): " ++ version
36+
putStrLn $ "完整信息 (Full info): " ++ name ++ " - " ++ version
37+
putStrLn ""
38+
39+
-- 列表操作
40+
putStrLn "🍎 列表示例 (List example):"
41+
let fruits = ["苹果", "香蕉", "橙子", "葡萄"]
42+
mapM_ (\(i, fruit) -> putStrLn $ show (i + 1) ++ ". " ++ fruit) (zip [0..] fruits)
43+
putStrLn ""
44+
45+
-- 条件判断
46+
let score = 85
47+
putStrLn "📊 成绩评估 (Score evaluation):"
48+
putStrLn $ evaluateScore score
49+
putStrLn ""
50+
51+
-- 循环示例
52+
putStrLn "🔄 循环输出 (Loop output):"
53+
mapM_ (\i -> putStrLn $ "" ++ show i ++ " 次输出 (Output #" ++ show i ++ "): Hello from CodeForge!") [1..5]
54+
putStrLn ""
55+
56+
-- 递归示例 (模拟while循环)
57+
putStrLn "🔁 递归示例 (Recursion example):"
58+
countDown 3
59+
putStrLn ""
60+
61+
putStrLn "🎯 CodeForge Haskell代码执行完成!"
62+
putStrLn "🎯 CodeForge Haskell execution completed!"
63+
putStrLn ""
64+
putStrLn "感谢使用 CodeForge 代码执行环境! 🚀"
65+
putStrLn "Thank you for using CodeForge! 🚀"
66+
67+
-- 评估分数的函数
68+
evaluateScore :: Int -> String
69+
evaluateScore score
70+
| score >= 90 = "优秀! (Excellent!)"
71+
| score >= 80 = "良好! (Good!)"
72+
| score >= 60 = "及格 (Pass)"
73+
| otherwise = "需要努力 (Need improvement)"
74+
75+
-- 递归倒计数函数 (模拟while循环)
76+
countDown :: Int -> IO ()
77+
countDown 0 = return ()
78+
countDown n = do
79+
putStrLn $ "递归循环: 第 " ++ show (4 - n) ++ ""
80+
countDown (n - 1)

src-tauri/src/plugins/haskell.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use super::{LanguagePlugin, PluginConfig};
2+
use std::vec;
3+
4+
pub struct HaskellPlugin;
5+
6+
impl LanguagePlugin for HaskellPlugin {
7+
fn get_order(&self) -> i32 {
8+
25
9+
}
10+
11+
fn get_language_name(&self) -> &'static str {
12+
"Haskell"
13+
}
14+
15+
fn get_language_key(&self) -> &'static str {
16+
"haskell"
17+
}
18+
19+
fn get_file_extension(&self) -> String {
20+
self.get_config()
21+
.map(|config| config.extension.clone())
22+
.unwrap_or_else(|| "hs".to_string())
23+
}
24+
25+
fn get_version_args(&self) -> Vec<&'static str> {
26+
vec!["--version"]
27+
}
28+
29+
fn get_path_command(&self) -> String {
30+
"which ghc".to_string()
31+
}
32+
33+
fn get_command(
34+
&self,
35+
_file_path: Option<&str>,
36+
_is_version: bool,
37+
_file_name: Option<String>,
38+
) -> String {
39+
if _is_version {
40+
let ghc_command = if self.get_execute_home().is_some() {
41+
"./ghc"
42+
} else {
43+
"ghc"
44+
};
45+
46+
return ghc_command.to_string();
47+
}
48+
49+
// 执行代码时
50+
if let Some(config) = self.get_config() {
51+
if let Some(run_cmd) = &config.run_command {
52+
return if let Some(file_name) = _file_name {
53+
run_cmd.replace("$filename", &file_name)
54+
} else {
55+
// 执行代码但没有文件名时,返回原始命令让框架处理 $filename 替换
56+
run_cmd.clone()
57+
};
58+
}
59+
}
60+
self.get_default_command()
61+
}
62+
63+
fn get_execute_args(&self, file_path: &str) -> Vec<String> {
64+
let ghc_command = if self.get_execute_home().is_some() {
65+
"./ghc"
66+
} else {
67+
"ghc"
68+
};
69+
70+
// 对于 Haskell,通常先编译再运行
71+
// 这里假设编译后的可执行文件名为 main
72+
let cmd = format!("{} {} -o main && ./main", ghc_command, file_path);
73+
74+
vec!["-c".to_string(), cmd]
75+
}
76+
77+
fn get_default_config(&self) -> PluginConfig {
78+
PluginConfig {
79+
enabled: true,
80+
language: String::from("haskell"),
81+
before_compile: Some(String::from("ghc $filename -o /tmp/main")),
82+
extension: String::from("hs"),
83+
execute_home: None,
84+
run_command: Some(String::from("/tmp/main")),
85+
after_compile: Some(String::from("rm -f /tmp/main /tmp/main.hi /tmp/main.o")),
86+
template: Some(String::from(
87+
"-- 在这里输入 Haskell 代码\n-- Haskell - 纯函数式编程语言\n",
88+
)),
89+
timeout: Some(30),
90+
console_type: Some(String::from("console")),
91+
}
92+
}
93+
94+
fn get_default_command(&self) -> String {
95+
self.get_config()
96+
.and_then(|config| config.run_command.clone())
97+
.unwrap_or_else(|| "./main".to_string())
98+
}
99+
}

src-tauri/src/plugins/manager.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::plugins::cpp::CppPlugin;
77
use crate::plugins::css::CssPlugin;
88
use crate::plugins::go::GoPlugin;
99
use crate::plugins::groovy::GroovyPlugin;
10+
use crate::plugins::haskell::HaskellPlugin;
1011
use crate::plugins::html::HtmlPlugin;
1112
use crate::plugins::java::JavaPlugin;
1213
use crate::plugins::javascript_browser::JavaScriptBrowserPlugin;
@@ -60,6 +61,7 @@ impl PluginManager {
6061
plugins.insert("php".to_string(), Box::new(PHPPlugin));
6162
plugins.insert("r".to_string(), Box::new(RPlugin));
6263
plugins.insert("cangjie".to_string(), Box::new(CangjiePlugin));
64+
plugins.insert("haskell".to_string(), Box::new(HaskellPlugin));
6365
plugins.insert(
6466
"javascript-nodejs".to_string(),
6567
Box::new(JavaScriptNodeJsPlugin),

src-tauri/src/plugins/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ pub mod cpp;
377377
pub mod css;
378378
pub mod go;
379379
pub mod groovy;
380+
pub mod haskell;
380381
pub mod html;
381382
pub mod java;
382383
pub mod javascript_browser;

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "CodeForge",
4-
"version": "25.0.3",
4+
"version": "25.0.4",
55
"identifier": "org.devlive.codeforge",
66
"build": {
77
"beforeDevCommand": "pnpm dev",

0 commit comments

Comments
 (0)