Skip to content

Commit 1594bcc

Browse files
authored
Merge pull request #58 from qianmoQ/dev-25.0.4
feat (language): 支持 Objective-C, Objective-C++ 语言
2 parents ea11039 + 8cfdd96 commit 1594bcc

13 files changed

Lines changed: 405 additions & 14 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ pnpm-lock.yaml
2929
go.mod
3030
.RData
3131
.Rhistory
32+
program

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ CodeForge 是一款轻量级、高性能的桌面代码执行器,专为开发
3939
<img src="public/icons/kotlin.svg" width="60" alt="Kotlin">
4040
<img src="public/icons/lua.svg" width="60" alt="Lua">
4141
<img src="public/icons/nodejs.svg" width="60" alt="Node.js">
42+
<img src="public/icons/objective-c.svg" width="60" alt="Objective-C">
43+
<img src="public/icons/objective-cpp.svg" width="60" alt="Objective-C++">
4244
<img src="public/icons/php.svg" width="60" alt="PHP">
4345
<img src="public/icons/python.svg" width="60" alt="Python 2">
4446
<img src="public/icons/python.svg" width="60" alt="Python 3">

public/icons/objective-c.svg

Lines changed: 6 additions & 0 deletions
Loading

public/icons/objective-cpp.svg

Lines changed: 9 additions & 0 deletions
Loading
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#import <Foundation/Foundation.h>
2+
3+
int main(int argc, const char * argv[]) {
4+
@autoreleasepool {
5+
printf("🎉 欢迎使用 CodeForge!\n");
6+
printf("Welcome to CodeForge!\n");
7+
printf("\n");
8+
9+
printf("=========================================\n");
10+
printf(" CodeForge Objective-C \n");
11+
printf("=========================================\n");
12+
printf("\n");
13+
14+
printf("✅ Objective-C运行成功! (Objective-C is working!)\n");
15+
printf("⚡ 这是Objective-C程序 (This is Objective-C program)\n");
16+
printf("\n");
17+
18+
int number1 = 10;
19+
int number2 = 20;
20+
int result = number1 + number2;
21+
22+
printf("🔢 简单计算 (Simple calculation):\n");
23+
printf("%d + %d = %d\n", number1, number2, result);
24+
printf("\n");
25+
26+
printf("📝 字符串操作 (String operations):\n");
27+
printf("平台名称 (Platform): CodeForge\n");
28+
printf("语言版本 (Language): Objective-C\n");
29+
printf("完整信息 (Full info): CodeForge - Objective-C\n");
30+
printf("\n");
31+
32+
printf("🍎 数组示例 (Array example):\n");
33+
NSArray *fruits = @[@"苹果", @"香蕉", @"橙子", @"葡萄"];
34+
for (int i = 0; i < fruits.count; i++) {
35+
printf("%d. %s\n", i + 1, [fruits[i] UTF8String]);
36+
}
37+
printf("\n");
38+
39+
int score = 85;
40+
printf("📊 成绩评估 (Score evaluation):\n");
41+
if (score >= 90) {
42+
printf("优秀! (Excellent!)\n");
43+
} else if (score >= 80) {
44+
printf("良好! (Good!)\n");
45+
} else if (score >= 60) {
46+
printf("及格 (Pass)\n");
47+
} else {
48+
printf("需要努力 (Need improvement)\n");
49+
}
50+
printf("\n");
51+
52+
printf("🔄 循环输出 (Loop output):\n");
53+
for (int i = 1; i <= 5; i++) {
54+
printf("%d 次输出 (Output #%d): Hello from CodeForge!\n", i, i);
55+
}
56+
printf("\n");
57+
58+
printf("🔁 While循环示例 (While loop example):\n");
59+
int counter = 1;
60+
while (counter <= 3) {
61+
printf("While循环: 第 %d\n", counter);
62+
counter++;
63+
}
64+
printf("\n");
65+
66+
printf("🎯 CodeForge Objective-C代码执行完成!\n");
67+
printf("🎯 CodeForge Objective-C execution completed!\n");
68+
printf("\n");
69+
printf("感谢使用 CodeForge 代码执行环境! 🚀\n");
70+
printf("Thank you for using CodeForge! 🚀\n");
71+
}
72+
return 0;
73+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#import <Foundation/Foundation.h>
2+
#include <iostream>
3+
#include <vector>
4+
#include <string>
5+
6+
int main(int argc, const char * argv[]) {
7+
@autoreleasepool {
8+
printf("🎉 欢迎使用 CodeForge!\n");
9+
printf("Welcome to CodeForge!\n");
10+
printf("\n");
11+
12+
printf("=========================================\n");
13+
printf(" CodeForge Objective-C++ \n");
14+
printf("=========================================\n");
15+
printf("\n");
16+
17+
printf("✅ Objective-C++运行成功! (Objective-C++ is working!)\n");
18+
printf("⚡ 这是Objective-C++程序 (This is Objective-C++ program)\n");
19+
printf("\n");
20+
21+
int number1 = 10;
22+
int number2 = 20;
23+
int result = number1 + number2;
24+
25+
printf("🔢 简单计算 (Simple calculation):\n");
26+
printf("%d + %d = %d\n", number1, number2, result);
27+
printf("\n");
28+
29+
printf("📝 字符串操作 (String operations):\n");
30+
std::string cppName = "CodeForge";
31+
std::string cppVersion = "Objective-C++";
32+
printf("平台名称 (Platform): %s\n", cppName.c_str());
33+
printf("语言版本 (Language): %s\n", cppVersion.c_str());
34+
printf("完整信息 (Full info): %s - %s\n", cppName.c_str(), cppVersion.c_str());
35+
printf("\n");
36+
37+
printf("🍎 数组示例 (Array example - Objective-C):\n");
38+
NSArray *fruits = @[@"苹果", @"香蕉", @"橙子", @"葡萄"];
39+
for (int i = 0; i < fruits.count; i++) {
40+
printf("%d. %s\n", i + 1, [fruits[i] UTF8String]);
41+
}
42+
printf("\n");
43+
44+
printf("🍇 Vector示例 (Vector example - C++):\n");
45+
std::vector<std::string> colors = {"红色", "蓝色", "绿色", "黄色"};
46+
for (size_t i = 0; i < colors.size(); i++) {
47+
printf("%zu. %s\n", i + 1, colors[i].c_str());
48+
}
49+
printf("\n");
50+
51+
int score = 85;
52+
printf("📊 成绩评估 (Score evaluation):\n");
53+
if (score >= 90) {
54+
printf("优秀! (Excellent!)\n");
55+
} else if (score >= 80) {
56+
printf("良好! (Good!)\n");
57+
} else if (score >= 60) {
58+
printf("及格 (Pass)\n");
59+
} else {
60+
printf("需要努力 (Need improvement)\n");
61+
}
62+
printf("\n");
63+
64+
printf("🔄 循环输出 (Loop output):\n");
65+
for (int i = 1; i <= 5; i++) {
66+
printf("第 %d 次输出 (Output #%d): Hello from CodeForge!\n", i, i);
67+
}
68+
printf("\n");
69+
70+
printf("🔁 While循环示例 (While loop example):\n");
71+
int counter = 1;
72+
while (counter <= 3) {
73+
printf("While循环: 第 %d 次\n", counter);
74+
counter++;
75+
}
76+
printf("\n");
77+
78+
printf("🎯 CodeForge Objective-C++代码执行完成!\n");
79+
printf("🎯 CodeForge Objective-C++ execution completed!\n");
80+
printf("\n");
81+
printf("感谢使用 CodeForge 代码执行环境! 🚀\n");
82+
printf("Thank you for using CodeForge! 🚀\n");
83+
}
84+
return 0;
85+
}

src-tauri/src/plugin.rs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,42 @@
11
use crate::plugins::{LanguageInfo, PluginManager};
22
use log::{debug, error, info};
3+
use regex::Regex;
34
use std::process::Command;
45
use tauri::State;
56
use tokio::sync::Mutex;
67

78
pub type PluginManagerState = Mutex<PluginManager>;
89

9-
// 通用的环境信息获取函数
10+
fn extract_version(output: &str) -> String {
11+
let output = output.trim();
12+
13+
let version_patterns = vec![
14+
r"(?i)version\s+([0-9]+\.[0-9]+\.[0-9]+(?:-[a-zA-Z0-9]+)?)",
15+
r"(?i)version\s+([0-9]+\.[0-9]+(?:\.[0-9]+)?)",
16+
r"\bv?([0-9]+\.[0-9]+\.[0-9]+(?:-[a-zA-Z0-9]+)?)\b",
17+
r"\bv?([0-9]+\.[0-9]+(?:\.[0-9]+)?)\b",
18+
r#""([0-9]+\.[0-9]+\.[0-9]+)""#,
19+
];
20+
21+
for pattern in version_patterns {
22+
if let Ok(re) = Regex::new(pattern) {
23+
if let Some(cap) = re.captures(output) {
24+
if let Some(version) = cap.get(1) {
25+
return version.as_str().to_string();
26+
}
27+
}
28+
}
29+
}
30+
31+
if let Some(first_line) = output.lines().next() {
32+
if !first_line.is_empty() {
33+
return first_line.to_string();
34+
}
35+
}
36+
37+
output.to_string()
38+
}
39+
1040
#[tauri::command]
1141
pub async fn get_info(
1242
language: String,
@@ -44,20 +74,27 @@ pub async fn get_info(
4474
.arg(plugin.get_path_command())
4575
.output();
4676

47-
let mut version = String::from_utf8_lossy(&version_out.stdout)
77+
let mut raw_version = String::from_utf8_lossy(&version_out.stdout)
4878
.trim()
4979
.to_string();
5080

51-
if version.is_empty() {
81+
if raw_version.is_empty() {
5282
info!(
5383
"获取环境 -> 调用插件 [ {} ] 版本为空,通过 stderr 获取",
5484
language
5585
);
56-
version = String::from_utf8_lossy(&version_out.stderr)
86+
raw_version = String::from_utf8_lossy(&version_out.stderr)
5787
.trim()
5888
.to_string();
5989
}
6090

91+
let version = extract_version(&raw_version);
92+
let final_version = if version.is_empty() {
93+
raw_version
94+
} else {
95+
version
96+
};
97+
6198
let path = if let Ok(path_out) = path_result {
6299
if path_out.status.success() {
63100
String::from_utf8_lossy(&path_out.stdout).trim().to_string()
@@ -71,7 +108,7 @@ pub async fn get_info(
71108
info!("获取环境 -> 调用插件 [ {} ] 完成", language);
72109
return Ok(LanguageInfo {
73110
installed: true,
74-
version,
111+
version: final_version,
75112
path,
76113
language: plugin.get_language_name().to_string(),
77114
});
@@ -90,7 +127,6 @@ pub async fn get_info(
90127
})
91128
}
92129

93-
// 获取支持的语言列表
94130
#[tauri::command]
95131
pub async fn get_supported_languages(
96132
plugin_manager: State<'_, PluginManagerState>,

src-tauri/src/plugins/manager.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use crate::plugins::javascript_nodejs::JavaScriptNodeJsPlugin;
1616
use crate::plugins::kotlin::KotlinPlugin;
1717
use crate::plugins::lua::LuaPlugin;
1818
use crate::plugins::nodejs::NodeJSPlugin;
19+
use crate::plugins::objective_c::ObjectiveCPlugin;
20+
use crate::plugins::objective_cpp::ObjectiveCppPlugin;
1921
use crate::plugins::php::PHPPlugin;
2022
use crate::plugins::python2::Python2Plugin;
2123
use crate::plugins::python3::Python3Plugin;
@@ -64,6 +66,8 @@ impl PluginManager {
6466
plugins.insert("cangjie".to_string(), Box::new(CangjiePlugin));
6567
plugins.insert("haskell".to_string(), Box::new(HaskellPlugin));
6668
plugins.insert("lua".to_string(), Box::new(LuaPlugin));
69+
plugins.insert("objective-c".to_string(), Box::new(ObjectiveCPlugin));
70+
plugins.insert("objective-cpp".to_string(), Box::new(ObjectiveCppPlugin));
6771
plugins.insert(
6872
"javascript-nodejs".to_string(),
6973
Box::new(JavaScriptNodeJsPlugin),

src-tauri/src/plugins/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ pub mod kotlin;
387387
pub mod lua;
388388
pub mod manager;
389389
pub mod nodejs;
390+
pub mod objective_c;
391+
pub mod objective_cpp;
390392
pub mod php;
391393
pub mod python2;
392394
pub mod python3;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
use super::{LanguagePlugin, PluginConfig};
2+
use std::vec;
3+
4+
pub struct ObjectiveCPlugin;
5+
6+
impl LanguagePlugin for ObjectiveCPlugin {
7+
fn get_order(&self) -> i32 {
8+
27
9+
}
10+
11+
fn get_language_name(&self) -> &'static str {
12+
"Objective-C"
13+
}
14+
15+
fn get_language_key(&self) -> &'static str {
16+
"objective-c"
17+
}
18+
19+
fn get_file_extension(&self) -> String {
20+
self.get_config()
21+
.map(|config| config.extension.clone())
22+
.unwrap_or_else(|| "m".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 clang".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 clang_command = if self.get_execute_home().is_some() {
41+
"./clang"
42+
} else {
43+
"clang"
44+
};
45+
46+
return clang_command.to_string();
47+
}
48+
49+
if let Some(config) = self.get_config() {
50+
if let Some(run_cmd) = &config.run_command {
51+
return if let Some(file_name) = _file_name {
52+
run_cmd.replace("$filename", &file_name)
53+
} else {
54+
run_cmd.clone()
55+
};
56+
}
57+
}
58+
self.get_default_command()
59+
}
60+
61+
fn get_default_config(&self) -> PluginConfig {
62+
PluginConfig {
63+
enabled: true,
64+
language: String::from("objective-c"),
65+
before_compile: Some(String::from(
66+
"clang -framework Foundation $filename -o program",
67+
)),
68+
extension: String::from("m"),
69+
execute_home: None,
70+
run_command: Some(String::from("./program")),
71+
after_compile: Some(String::from("rm -f program")),
72+
template: Some(String::from(
73+
"// Objective-C 示例代码 - CodeForge 代码执行环境\n\n",
74+
)),
75+
timeout: Some(30),
76+
console_type: Some(String::from("console")),
77+
}
78+
}
79+
80+
fn get_default_command(&self) -> String {
81+
self.get_config()
82+
.and_then(|config| config.run_command.clone())
83+
.unwrap_or_else(|| "./program".to_string())
84+
}
85+
}

0 commit comments

Comments
 (0)